Java
Arrays.sort(数组) //排序
不讲究顺序的解答,都可以考虑一下排序是否可行。
39. 组合总和
错误解答
在写的时候需要注意,sum -= candidates[i];
很重要,也是回溯的一部分。
解答重复了。是因为回溯的for循环理解错了。
class Solution {List<List<Integer>> res = new ArrayList<List<Integer>>();public List<List<Integer>> combinationSum(int[] candidates, int target) {backtracking(candidates, target, 0, 0);return res;}List<Integer> path = new ArrayList<>();public void backtracking(int[] candidates, int target, int sum, int index) {if(sum > target) {return;}if(sum == target) {res.add(new ArrayList<>(path));return;}for(int i=0; i<candidates.length; i++) {sum += candidates[i];path.add(candidates[i]);backtracking(candidates,target,sum,i);sum -= candidates[i];path.remove(path.size()-1);}}
}
正确
- 修改成下面这样就对了
优化
不讲究顺序的解答,都可以考虑一下排序是否可行。
剪枝要先排序。
class Solution {List<List<Integer>> res = new ArrayList<List<Integer>>();public List<List<Integer>> combinationSum(int[] candidates, int target) {Arrays.sort(candidates);backtracking(candidates, target, 0, 0);return res;}List<Integer> path = new ArrayList<>();public void backtracking(int[] candidates, int target, int sum, int index) {if(sum == target) {res.add(new ArrayList<>(path));return;}for(int i=index; i<candidates.length; i++) {sum += candidates[i];if (sum > target) break;path.add(candidates[i]);backtracking(candidates,target,sum,i);sum -= candidates[i];path.remove(path.size()-1);}}
}
40.组合总和II
错误解法
想得太简单了……
class Solution {List<List<Integer>> res = new ArrayList<List<Integer>>();public List<List<Integer>> combinationSum2(int[] candidates, int target) {Arrays.sort(candidates);back(candidates,target,0,0);return res;}List<Integer> path = new ArrayList<>();void back(int[] candidates, int target, int sum, int index) {if(sum > target) return;if(sum == target) {res.add(new ArrayList(path));}for(int i=index; i<candidates.length; i++) {path.add(candidates[i]);sum+=candidates[i];back(candidates,target,sum,index+1);sum-=candidates[i];path.remove(path.size()-1); }}
}
与之前题目的区别
之前这两题,原本的数组中的元素是不重复的。但本题(40)是重复的,也就是说,[1,1,7],target=8那会有两种情况[1,7] [1,7],但这个答案是重复的,需要去重。
正确解法
本题中可以有重复的元素,因为数组中的元素是重复的。
去重是在同一树层中去除。但树层中怎么去重呢?用到了use数组。
class Solution {List<List<Integer>> res = new ArrayList<List<Integer>>();Boolean[] used;public List<List<Integer>> combinationSum2(int[] candidates, int target) {used = new Boolean[candidates.length];Arrays.fill(used, false);Arrays.sort(candidates);back(candidates,target,0,0);return res;}List<Integer> path = new ArrayList<>();void back(int[] candidates, int target, int sum, int index) {if(sum == target) {res.add(new ArrayList(path));}for(int i=index; i<candidates.length; i++) {if(i>0 && candidates[i]==candidates[i-1] && !used[i-1]) {continue;}if(sum > target) break; //去重-树枝path.add(candidates[i]);sum+=candidates[i];used[i] = true;back(candidates,target,sum,i+1);sum-=candidates[i];used[i] = false;path.remove(path.size()-1); }}
}
思考:代码中,这个continue什么意思?这里可不可以写return?不可以。
131.分割回文串
那么难究竟难在什么地方呢?
切割问题可以抽象为组合问题
如何模拟那些切割线
切割问题中递归如何终止
在递归循环中如何截取子串
如何判断回文
- 注意
第二十行,为什么还要continue?
因为ab不是回文,没准aba就是了。
而且也不用担心当前不是回文,之后不是怎么办,因为可以切割出单个字符
class Solution {List<List<String>> res = new ArrayList<>();List<String> path = new ArrayList<>();public List<List<String>> partition(String s) {backtracking(s,0);return res;}void backtracking(String s, int startIndex) {if(startIndex == s.length()) {res.add(new ArrayList(path));return;}for(int i=startIndex; i<s.length(); i++) {if(ishuiwen(s,startIndex,i)) {String str = s.substring(startIndex, i + 1);path.add(str);} else {continue;}backtracking(s,i+1);path.removeLast();}}Boolean ishuiwen(String s, int left, int right) {for(int i=left,j=right; i<=j; i++, j--) {if(s.charAt(i) != s.charAt(j)) {return false;}}return true;}
}