39. 组合总
题目链接:力扣题目链接
思路:回溯,成员变量result用于保存最后的结果数组,current用于保存不停添加删除的数组来验证总和是否等于target。需要注意的是回溯中的for循环每次开始的点不能小于之前一次回溯for循环的值,否则会重复。
class Solution {
List<List<Integer>> result = new ArrayList<>();
List<Integer> current = new ArrayList<>();
public List<List<Integer>> combinationSum(int[] candidates, int target) {
backtracking(candidates,target,0,0);
return result;
}
public void backtracking(int[] candidates,int target,int sum,int j){
if(sum == target){
result.add(new ArrayList<>(current));
return;
}else if(sum <target){
for(int i=j;i<candidates.length;i++){
current.add(candidates[i]);
backtracking(candidates,target,sum+candidates[i],i);
current.remove(current.size() - 1);
}
}else{
return;
}
return;
}
}
40.组合总和II
题目链接:力扣题目链接
思路:和“39. 组合总和”差不多只是先sort排序,然后for循环没起其实是之前的i+1避免同一个candidate加入到current中,同时使用contains检查result是否有重复再加入新的current。但是弊端效率低,所以改进在for循环中增加一个循环,这个循环可以避免使用contains降低时间复杂度。
if(i>j&&candidates[i] == candidates[i - 1]){
continue;
}
131.分割回文串
题目链接:力扣题目链接
思路:将String看成数组,然后每个for循环看成切割的点位,判断当前切割点位是否是回文,不是就继续for循环,否则就加入current,然后递归。
class Solution {
List<List<String>> result = new ArrayList<>();
List<String> current = new ArrayList<>();
public List<List<String>> partition(String s) {
backtracing(s.toCharArray(),0);
return result;
}
public void backtracing(char[] str,int j){
if(j>=str.length){
result.add(new ArrayList<>(current));
return;
}
for(int i=j;i<str.length;i++){
if(!isReStr(Arrays.copyOfRange(str, j, i+1))){
continue;
}
current.add(new String(Arrays.copyOfRange(str, j, i+1)));
backtracing(str,i+1);
current.remove(current.size()-1);
}
}
public boolean isReStr(char[] str){
int a=0;
int b=str.length-1;
while(a<b){
if(str[a]!=str[b]){
return false;
}
a++;
b--;
}
return true;
}
}
时间:1.5h