当前位置:  首页>> 技术小册>> 数据结构与算法(中)

难度:
Hard

题意:

  1. 给定两个字符串,问最少要交换多少次,使得A变成了B,A和B里面的字母都是a-f

思路:

  • 将字符串A到字符串B的变换看成图,那么这张图就是一个一个环构成的。环上,交换的次数等于环的长度-1,所以这个题目变成了,将图拆成环,使环的个数最大
  • 后面就是纯搜索,注意状态合并。状态定义为,当前图的状态(6*6的矩阵),然后在图上寻找所有的可行环,分别去掉,转成下一个状态

代码:

  1. class Solution {
  2. private class State implements Comparable<State> {
  3. int[] a;
  4. int total;
  5. State() {
  6. a = new int[6];
  7. Arrays.fill(a, 0);
  8. total = 0;
  9. }
  10. State(int[] a, int total) {
  11. this.a = Arrays.copyOf(a, a.length);
  12. this.total = total;
  13. }
  14. private int get(int x, int y) {
  15. return (a[x] >> (y * 4)) & 15;
  16. }
  17. private void minus(int x, int y) {
  18. a[x] -= 1 << (y * 4);
  19. total--;
  20. }
  21. private void add(int x, int y) {
  22. a[x] += 1 << (y * 4);
  23. total++;
  24. }
  25. @Override
  26. public int compareTo(State o) {
  27. if (Integer.compare(total, o.total) == 0) {
  28. for (int i = 0;i < 6;i++) {
  29. if (Integer.compare(a[i], o.a[i]) != 0) {
  30. return Integer.compare(a[i], o.a[i]);
  31. }
  32. }
  33. return 0;
  34. } else {
  35. return -Integer.compare(total, o.total);
  36. }
  37. }
  38. }
  39. private void extand(boolean[] flag, int[] pos, TreeMap<State, Integer> stateMap, State current, int idx) {
  40. if (current.get(pos[idx - 1], pos[0]) != 0) {
  41. State next = new State(current.a, current.total);
  42. for (int i = 0;i < idx - 1;i++) {
  43. next.minus(pos[i], pos[i + 1]);
  44. }
  45. next.minus(pos[idx - 1], pos[0]);
  46. int value = stateMap.get(current);
  47. value += idx - 1;
  48. if (stateMap.containsKey(next)) {
  49. value = value < stateMap.get(next) ? value : stateMap.get(next);
  50. stateMap.put(next, value);
  51. } else {
  52. stateMap.put(next, value);
  53. }
  54. }
  55. if (idx == 6) {
  56. return;
  57. }
  58. for (int i = 0;i < 6;i++) {
  59. if (!flag[i] && current.get(pos[idx - 1], i) != 0) {
  60. flag[i] = true;
  61. pos[idx] = i;
  62. extand(flag, pos, stateMap, current, idx + 1);
  63. flag[i] = false;
  64. }
  65. }
  66. }
  67. private void solve(TreeMap<State, Integer> stateMap, State current) {
  68. boolean[] flag = new boolean[6];
  69. Arrays.fill(flag, false);
  70. int[] pos = new int[6];
  71. int min = -1;
  72. for (int i = 0;i < 6;i++) {
  73. if (current.a[i] != 0) {
  74. min = i;
  75. break;
  76. }
  77. }
  78. if (min == -1) {
  79. return;
  80. }
  81. flag[min] = true;
  82. pos[0] = min;
  83. extand(flag, pos, stateMap, current, 1);
  84. }
  85. public int kSimilarity(String A, String B) {
  86. TreeMap<State, Integer> stateMap = new TreeMap<State, Integer>();
  87. State start = new State();
  88. for (int i = 0;i < A.length();i++) {
  89. if (A.charAt(i) != B.charAt(i)) {
  90. start.add(A.charAt(i) - 'a', B.charAt(i) - 'a');
  91. }
  92. }
  93. int ret = 0x3fffffff;
  94. stateMap.put(start, 0);
  95. while (!stateMap.isEmpty()) {
  96. State current = stateMap.firstKey();
  97. if (current.total == 0) {
  98. ret = ret < stateMap.get(current) ? ret : stateMap.get(current);
  99. } else {
  100. solve(stateMap, current);
  101. }
  102. stateMap.remove(current);
  103. }
  104. return ret;
  105. }
  106. }

该分类下的相关小册推荐: