复习 77 组合 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 class Solution { List<List<Integer>> result = new ArrayList <>(); List<Integer> path = new ArrayList <>(); public List<List<Integer>> combine (int n, int k) { backTracking(n, k ,1 ); return result; } private void backTracking (int n, int k, int start) { if (path.size() == k){ result.add(new ArrayList <>(path)); return ; } for (int i = start; i <= n - (k - path.size()) + 1 ; i++){ path.add(i); backTracking(n , k, i + 1 ); path.remove(path.size() - 1 ); } } }
17 电话号码的字母组合 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 class Solution { String[] numString = new String [] {"" , "" , "abc" , "def" , "ghi" , "jkl" , "mno" , "pqrs" , "tuv" , "wxyz" }; List<String> result = new ArrayList <>(); StringBuilder sb = new StringBuilder (); public List<String> letterCombinations (String digits) { if (digits == null || digits.length() == 0 ) return result; backTracking(digits, 0 ); return result; } private void backTracking (String digits, int start) { if (sb.length() == digits.length()){ result.add(sb.toString()); return ; } String str = numString[digits.charAt(start) - '0' ]; for (int i = 0 ; i< str.length(); i++){ sb.append(str.charAt(i)); backTracking(digits, start + 1 ); sb.deleteCharAt(sb.length() - 1 ); } } }
216 组合总和III 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 class Solution { List<List<Integer>> result = new ArrayList <>(); List<Integer> path = new ArrayList <>(); public List<List<Integer>> combinationSum3 (int k, int n) { backTracking(k , n, 1 ); return result; } private void backTracking (int k, int n , int start) { if (n < 0 ) return ; if (n == 0 && path.size() == k){ result.add(new ArrayList <>(path)); return ; } for (int i = start; i <= 9 - (k - path.size()) + 1 ; i++){ path.add(i); n -= i; backTracking(k, n, i + 1 ); n += i; path.remove(path.size() - 1 ); } } }
39 组合总和 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 class Solution { List<List<Integer>> result = new ArrayList <>(); List<Integer> path = new ArrayList <>(); public List<List<Integer>> combinationSum (int [] candidates, int target) { if (candidates == null || candidates.length == 0 ) return result; Arrays.sort(candidates); backTracking(candidates, target, 0 ); return result; } private void backTracking (int [] candidates, int target, int start) { if (target < 0 ) return ; if (target == 0 ){ result.add(new ArrayList <>(path)); return ; } for (int i = start; i < candidates.length; i++){ path.add(candidates[i]); target -= candidates[i]; backTracking(candidates, target, i); target += candidates[i]; path.remove(path.size() - 1 ); } } }
40 组合总和II 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 class Solution { List<Integer> path = new ArrayList <>(); List<List<Integer>> result = new ArrayList <>(); boolean [] used; public List<List<Integer>> combinationSum2 (int [] candidates, int target) { used = new boolean [candidates.length]; Arrays.sort(candidates); Arrays.fill(used, false ); backTracking(candidates, target, 0 ); return result; } private void backTracking (int [] candidates, int target, int start) { if (target == 0 ){ result.add(new ArrayList <>(path)); return ; } for (int i = start; i < candidates.length; i++){ if (target < 0 ) break ; if (i > 0 && candidates[i] == candidates[i - 1 ] && !used[i - 1 ]) continue ; path.add(candidates[i]); used[i] = true ; target -= candidates[i]; backTracking(candidates, target, i + 1 ); target += candidates[i]; used[i] = false ; path.remove(path.size() - 1 ); } } }
131 分割回文串 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 class Solution { List<List<String>> result = new ArrayList <>(); List<String> path = new ArrayList <>(); public List<List<String>> partition (String s) { if (s == null || s.length() == 0 ) return result; backTracking(s, 0 ); return result; } private void backTracking (String s, int start) { if (start == s.length()){ result.add(new ArrayList <>(path)); return ; } for (int i = start; i < s.length(); i++){ if (isPalindrome(s, start, i)){ path.add(s.substring(start, i + 1 )); backTracking(s, i + 1 ); path.remove(path.size() - 1 ); } } } private boolean isPalindrome (String s, int start, int end) { while (start <= end){ if (s.charAt(start) != s.charAt(end)) return false ; start++; end--; } return true ; } }
93 复原ip地址 注意: 判断数字问题 判断最后一段符合逻辑 注意对s的操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 class Solution { List<String> result = new ArrayList <>(); public List<String> restoreIpAddresses (String s) { if (s.length() == 0 || s.length() > 12 ) return result; backTracking(s, 0 , 0 ); return result; } private void backTracking (String s, int start, int points) { if (points == 3 ){ if (isValid(s, start, s.length() - 1 )){ result.add(s); } return ; } for (int i = start; i < s.length(); i++){ if (isValid(s, start, i)){ s = s.substring(0 , i + 1 ) + "." + s.substring(i + 1 ); points++; backTracking(s, i + 2 , points); points--; s = s.substring(0 , i + 1 ) + s.substring(i + 2 ); } else break ; } } private boolean isValid (String s, int start, int end) { if (start > end) return false ; if (s.charAt(start) == '0' && start != end) return false ; int num = 0 ; for (int i = start; i <= end; i++){ if (s.charAt(i) - '0' > 9 || s.charAt(i) - '0' < 0 ) return false ; num = num * 10 + s.charAt(i) - '0' ; if (num > 255 ) return false ; } return true ; } }
78 子集 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 class Solution { List<List<Integer>> result = new ArrayList <>(); List<Integer> path = new ArrayList <>(); public List<List<Integer>> subsets (int [] nums) { backTracking(nums, 0 ); return result; } private void backTracking (int [] nums, int start) { result.add(new ArrayList (path)); for (int i = start; i < nums.length; i++){ path.add(nums[i]); backTracking(nums, i + 1 ); path.remove(path.size() - 1 ); } } }
90 子集II 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 class Solution { List<List<Integer>> result = new ArrayList <>(); List<Integer> path = new ArrayList <>(); boolean [] used; public List<List<Integer>> subsetsWithDup (int [] nums) { used = new boolean [nums.length]; Arrays.fill(used, false ); Arrays.sort(nums); backTracking(nums, 0 ); return result; } private void backTracking (int [] nums, int start) { result.add(new ArrayList (path)); for (int i = start; i < nums.length; i++){ if (i > 0 && nums[i] == nums[i - 1 ] && !used[i - 1 ]) continue ; path.add(nums[i]); used[i] = true ; backTracking(nums, i + 1 ); used[i] = false ; path.remove(path.size() - 1 ); } } }
491 递增子序列 利用在回溯函数里面的hashset或者int[] 记录本层通过的点 利用if语句判断是否递增,或者是否是重复的值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 class Solution { List<List<Integer>> result = new ArrayList <>(); List<Integer> path = new ArrayList <>(); public List<List<Integer>> findSubsequences (int [] nums) { backTracking(nums, 0 ); return result; } private void backTracking (int [] nums, int start) { if (path.size() >= 2 ){ result.add(new ArrayList <>(path)); } int [] used = new int [201 ]; for (int i = start; i < nums.length; i++){ if (!path.isEmpty() && path.get(path.size() - 1 ) > nums[i] || used[nums[i] + 100 ] == 1 ) continue ; path.add(nums[i]); used[nums[i] + 100 ] = 1 ; backTracking(nums, i + 1 ); path.remove(path.size() - 1 ); } } private boolean isNonDecreasing (List<Integer> nums) { for (int i = 1 ; i < nums.size(); i++){ if (nums.get(i) < nums.get(i - 1 )){ return false ; } } return true ; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 class Solution { List<List<Integer>> result = new ArrayList <>(); List<Integer> path = new ArrayList <>(); public List<List<Integer>> findSubsequences (int [] nums) { backTracking(nums, 0 ); return result; } private void backTracking (int [] nums, int start) { if (path.size() >= 2 ){ result.add(new ArrayList <>(path)); } Set<Integer> set = new HashSet <>(); for (int i = start; i < nums.length; i++){ if (!path.isEmpty() && path.get(path.size() - 1 ) > nums[i] || set.contains(nums[i])) continue ; set.add(nums[i]); path.add(nums[i]); backTracking(nums, i + 1 ); path.remove(path.size() - 1 ); } } }
46 全排列 第一种 利用used记录path里面有没有nums[i]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 class Solution { List<List<Integer>> result = new ArrayList <>(); List<Integer> path = new ArrayList <>(); boolean [] used; public List<List<Integer>> permute (int [] nums) { used = new boolean [nums.length]; backTracking(nums); return result; } private void backTracking (int [] nums) { if (path.size() == nums.length){ result.add(new ArrayList <>(path)); return ; } for (int i = 0 ; i < nums.length; i++){ if (used[i]) continue ; used[i] = true ; path.add(nums[i]); backTracking(nums); used[i] = false ; path.removeLast(); } } }
第二种直接通过检查path里面有没有nums[i] 元素判断 List 有个 removeLast 方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 class Solution { List<List<Integer>> result = new ArrayList <>(); List<Integer> path = new ArrayList <>(); public List<List<Integer>> permute (int [] nums) { backTracking(nums); return result; } private void backTracking (int [] nums) { if (path.size() == nums.length){ result.add(new ArrayList <>(path)); return ; } for (int i = 0 ; i < nums.length; i++){ if (path.contains(nums[i])) continue ; path.add(nums[i]); backTracking(nums); path.removeLast(); } } }
47 全排列II 去重代码中 !used[i - 1] 是树层去重 used[i - 1] 是树枝去重 要确定used[i] 是否为false, 因为i一直是从0开始的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 class Solution { List<List<Integer>> result = new ArrayList <>(); List<Integer> path = new ArrayList <>(); boolean [] used; public List<List<Integer>> permuteUnique (int [] nums) { used = new boolean [nums.length]; Arrays.sort(nums); backTracking(nums); return result; } private void backTracking (int [] nums) { if (path.size() == nums.length){ result.add(new ArrayList <>(path)); return ; } for (int i = 0 ; i < nums.length; i++){ if (i > 0 && nums[i] == nums[i - 1 ] && !used[i - 1 ]) continue ; if (used[i] == false ){ used[i] = true ; path.add(nums[i]); backTracking(nums); path.removeLast(); used[i] = false ; } } } }