● 39. 组合总和
三个问题,第一个是又忘记新建ArrayList赋值到res里面了
第二个是忘记组合的含义了,是无序,也就是startindex的确定,这导致我在答案集合中出现了重复。。。。进入到下一个backTracking后,一定不能再从0开始了。而是从当前元素开始,因为可以重复引用。
最后一个是忘记把sum减去当前的值了。导致结果错误。
class Solution {
List<Integer> path = new ArrayList<>();
List<List<Integer>> res = new ArrayList<>();
public List<List<Integer>> combinationSum(int[] candidates, int target) {
backTracking(candidates,target,0,0);
return res;
}
public void backTracking(int[] candidates, int target,int sum,int startIndex){
if(sum>target){
return;
}
if(sum==target){
res.add(new ArrayList<>(path));
return;
}
for(int i = startIndex;i<candidates.length;i++){
path.add(candidates[i]);
sum+=candidates[i];
backTracking(candidates,target,sum,i);
sum-=candidates[i];
path.remove(path.size()-1);
}
}
}
下面加了剪枝,要在for里面做文章,不过要先对数组排序
class Solution {
List<Integer> path = new ArrayList<>();
List<List<Integer>> res = new ArrayList<>();
public List<List<Integer>> combinationSum(int[] candidates, int target) {
Arrays.sort(candidates);
backTracking(candidates,target,0,0);
return res;
}
public void backTracking(int[] candidates, int target,int sum,int startIndex){
if(sum>target){
return;
}
if(sum==target){
res.add(new ArrayList<>(path));
return;
}
for(int i = startIndex;i<candidates.length&&sum+candidates[i]<=target;i++){
path.add(candidates[i]);
sum+=candidates[i];
backTracking(candidates,target,sum,i);
sum-=candidates[i];
path.remove(path.size()-1);
}
}
}
● 40.组合总和II
先排序,然后去重,我们要去重的是同一树层上的“使用过”,同一树枝上的都是一个组合里的元素,不用去重。
引入了used数组。
if(i>0&&candidates[i-1]==candidates[i]&&used[i-1]==false){
continue;
}
这个终止条件,必须要配合使用,拿【1,1,2】举例,我现在到第二个1了,当我与前面的1相同而且前面的1在此刻没有使用,我才把这个情况排除掉。因为什么呢,当我在处理第一个1的时候,我就已经包含了第二个1的所有情况了。。。。。所以说,第二个1的情况就可以跳过了。
class Solution {
List<Integer> path = new ArrayList<>();
List<List<Integer>> res = new ArrayList<>();
public List<List<Integer>> combinationSum2(int[] candidates, int target) {
boolean[] used = new boolean[candidates.length];
Arrays.sort(candidates);
backTracking(candidates,target,0,0,used);
return res;
}
public void backTracking(int[] candidates,int target, int sum, int startIndex, boolean[] used){
if(sum>target){
return;
}
if(sum==target){
res.add(new ArrayList<>(path));
return;
}
for(int i = startIndex;i<candidates.length;i++){
if(i>0&&candidates[i-1]==candidates[i]&&used[i-1]==false){
continue;
}
sum+=candidates[i];
path.add(candidates[i]);
used[i] = true;
backTracking(candidates,target,sum,i+1,used);
sum-=candidates[i];
path.remove(path.size()-1);
used[i] = false;
}
}
}
● 131.分割回文串
还是有点没想明白这这分割问题是怎么抽象成回溯问题的。。。。。
substring(左闭右开);
又出现了引用拷贝问题。。。。。
class Solution {
List<String> path = new ArrayList<>();
List<List<String>> res= new ArrayList<>();
public List<List<String>> partition(String s) {
backTracking(s,0);
return res;
}
public 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(isPalindrome(s,startIndex,i)){
String str = s.substring(startIndex, i + 1);
path.add(str);
}else{
continue;
}
backTracking(s,i+1);
path.remove(path.size()-1);
}
}
public boolean isPalindrome(String s,int start,int end){
while(start<end){
if(s.charAt(start)!=s.charAt(end)){
return false;
}
start++;
end--;
}
return true;
}
}