这四个使用DFS来求解所有组合和排列的例子很有代表性,这里做一个总结:
1.不带重复元素的子集问题
1 public ArrayList<ArrayList<Integer>> subsets(int[] nums) { 2 // write your code here 3 ArrayList<ArrayList<Integer>> results = new ArrayList<>(); 4 if (nums == null || nums.length == 0) { 5 return results; 6 } 7 Arrays.sort(nums); 8 DFS(results, new ArrayList<Integer>(), nums, 0); 9 return results; 10 } 11 public void DFS(ArrayList<ArrayList<Integer>> results, ArrayList<Integer> cur, 12 int[] nums, int start) { 13 results.add(new ArrayList<Integer>(cur)); 14 for (int i = start; i < nums.length; i++) { 15 cur.add(nums[i]); 16 DFS(results, cur, nums, i+1); 17 cur.remove(cur.size()-1); 18 } 19 }
2.带重复元素的子集问题
1 public ArrayList<ArrayList<Integer>> subsetsWithDup(ArrayList<Integer> S) { 2 // write your code here 3 ArrayList<ArrayList<Integer>> results = new ArrayList<>(); 4 if (S == null || S.size() == 0) { 5 return results; 6 } 7 Collections.sort(S); 8 DFS(results, new ArrayList<Integer>(), S, 0); 9 return results; 10 } 11 public void DFS(ArrayList<ArrayList<Integer>> results, 12 ArrayList<Integer> cur, 13 ArrayList<Integer> S, 14 int start) { 15 results.add(new ArrayList<>(cur)); 16 for (int i = start; i < S.size(); i++) { 17 if(i != start && S.get(i) == S.get(i - 1)) { 18 continue; 19 } 20 cur.add(S.get(i)); 21 DFS(results, cur, S, i+1); 22 cur.remove(cur.size()-1); 23 } 24 }
3.不带重复元素的全排列问题
1 public List<List<Integer>> permute(int[] nums) { 2 // write your code here 3 List<List<Integer>> results = new ArrayList<List<Integer>>(); 4 if (nums == null || nums.length == 0) { 5 results.add(new ArrayList<Integer>()); 6 return results; 7 } 8 boolean[] used = new boolean[nums.length]; 9 DFS(results, new ArrayList<Integer>(), nums, used); 10 return results; 11 } 12 public void DFS(List<List<Integer>> results, List<Integer> cur, int[] nums, boolean[] used) { 13 if (cur.size() == nums.length) { 14 results.add(new ArrayList<Integer>(cur)); 15 return; 16 } 17 for(int i = 0; i<nums.length; i++) { 18 if (used[i]) { 19 continue; 20 } 21 used[i] =true; 22 cur.add(nums[i]); 23 DFS(results, cur, nums, used); 24 used[i] =false; 25 cur.remove(cur.size()-1); 26 } 27 }
4.带重负元素的全排列问题
1 public List<List<Integer>> permuteUnique(int[] nums) { 2 // Write your code here 3 List<List<Integer>> results = new ArrayList<List<Integer>>(); 4 if (nums == null || nums.length == 0) { 5 results.add(new ArrayList<Integer>()); 6 return results; 7 } 8 Arrays.sort(nums); 9 boolean[] used = new boolean[nums.length]; 10 DFS(results, new ArrayList<Integer>(), used, nums); 11 return results; 12 } 13 public void DFS(List<List<Integer>> results, List<Integer> cur, boolean[] used, int[] nums) { 14 if (cur.size() == nums.length) { 15 results.add(new ArrayList<Integer>(cur)); 16 return; 17 } 18 for (int i = 0; i < nums.length; i++) { 19 if (used[i]) { 20 continue; 21 } 22 if (i > 0 && nums[i] == nums[i - 1] && !used[i-1]) { 23 continue; 24 } 25 used[i] = true; 26 cur.add(nums[i]); 27 DFS(results, cur, used, nums); 28 used[i] = false; 29 cur.remove(cur.size() -1); 30 } 31 }
寻找丢失的数 II*
给一个由 1 - n
的整数随机组成的一个字符串序列,其中丢失了一个整数,请找到它。
回溯,当前位置可以单独,也可以和下一个结合,当前为0一定不行。curIndex控制啥时候结束。
1 public int findMissing2(int n, String str) { 2 // Write your code here 3 if (n < 1 || str == null) { 4 return 0; 5 } 6 char[] chars = str.toCharArray(); 7 boolean[] appeared = new boolean[n + 1]; 8 int[] curIndex = {0}; 9 help(appeared, chars, curIndex, n); 10 for (int i = 1; i < appeared.length; i++) { 11 if (!appeared[i]) { 12 return i; 13 } 14 } 15 return -1; 16 } 17 public void help(boolean[] appeared, char[] chars, int[] curIndex, int n) { 18 if (curIndex[0] >= chars.length) { 19 return; 20 } 21 if (chars[curIndex[0]] == '0') { 22 return; 23 } 24 if (!appeared[chars[curIndex[0]] - '0']) { 25 appeared[chars[curIndex[0]] - '0'] = true; 26 curIndex[0]++; 27 help(appeared, chars, curIndex, n); 28 if (curIndex[0] >= chars.length) { 29 return; 30 } 31 curIndex[0]--; 32 appeared[chars[curIndex[0]] - '0'] = false; 33 } 34 if (curIndex[0] < chars.length - 1) { 35 int c1 = chars[curIndex[0]] - '0'; 36 int c2 = chars[curIndex[0] + 1] - '0'; 37 int newnum = c1 * 10 + c2; 38 if (newnum <= n && !appeared[newnum]) { 39 appeared[newnum] = true; 40 curIndex[0] += 2; 41 help(appeared, chars, curIndex, n); 42 if (curIndex[0] >= chars.length) { 43 return; 44 } 45 curIndex[0]-=2; 46 appeared[newnum] = false; 47 } 48 } 49 }