代码随想录算法训练营第27天 | 39. 组合总和,40. 组合总和 II,131. 分割回文串
39. 组合总和
- 终止条件 当sum>=target时停止 若=就加入result
- for循环 中的 startindex 是用来控制 i 不要每次都从起点开始 因为组合问题 是不讲顺序的 5 2 和 2 5 是一样的
- 然后向下递归时 传入startindex 参数时 要看题目 是否可以重复值 若不可以 就传入i+1
class Solution {
List<List<Integer>> result = new ArrayList<>();
List<Integer> path = new ArrayList<>();
public List<List<Integer>> combinationSum(int[] candidates, int target) {
backtracing(0,candidates,target,0);
return result;
}
public void backtracing(int sum,int[] candidates, int target, int index){
if(sum>=target){
if(sum==target){
result.add(new ArrayList(path));
return;
}else{
return;
}
}
for(int i=index;i<candidates.length;i++){
sum+=candidates[i];
path.add(candidates[i]);
backtracing(sum,candidates,target,i);
sum-=candidates[i];
path.remove(path.size()-1);
}
return;
}
}
40. 组合总和 II
- 输入数组中有重复元素 但是结果中不能有重复组合
- 可以将数组排序 创建一个标志数组 用来区分 每个元素是处于 树层还是处于树枝
- 在同一个树枝中 不需要去重
- 假若 相邻两个元素相等 并且前面一个元素 没有正在被用 那么就是树层去重 用continue跳过这个元素的递归
class Solution {
List<List<Integer>> result = new ArrayList<>();
List<Integer> path = new ArrayList<>();
public List<List<Integer>> combinationSum2(int[] candidates, int target) {
boolean[] used = new boolean[candidates.length];
Arrays.fill(used,false);
Arrays.sort(candidates);
backtracing(0,candidates,target,0,used);
return result;
}
public void backtracing(int sum, int[] candidates, int target, int startIndex, boolean[] used){
if(sum>=target){
if(sum==target){
result.add(new ArrayList<>(path));
return;
}else{
return;
}
}
for(int i=startIndex;i<candidates.length;i++){
if(i>0 && candidates[i]==candidates[i-1] && used[i-1]==false){
continue;
}
sum+=candidates[i];
used[i]=true;
path.add(candidates[i]);
backtracing(sum,candidates,target,i+1,used);
sum-=candidates[i];
used[i]=false;
path.remove(path.size()-1);
}
return;
}
}
131. 分割回文串
- 每一段回文串可以用 startindex和i来切割
- 若为回文 就加入数组
- 判断回文串时 StringBuilder类 的 .reverse()会always true 都要转化成String .toString().equals()
class Solution {
List<List<String>> result = new ArrayList<>();
List<String> path = new ArrayList<>();
public List<List<String>> partition(String s) {
backtracing(s,0);
return result;
}
public static boolean isPalindrome(String s, int start, int end){
s = s.substring(start,end+1);
StringBuilder sb = new StringBuilder(s);
return sb.toString().equals(sb.reverse().toString());
}
public void backtracing(String s, int startIndex){
if(startIndex>=s.length()){
result.add(new ArrayList<>(path));
return;
}
for(int i=startIndex;i<s.length();i++){
if(isPalindrome(s,startIndex,i)){
path.add(s.substring(startIndex,i+1));
}else{
continue;
}
backtracing(s,i+1);
path.remove(path.size()-1);
}
return;
}
}