算法day20 | leetcode39. 组合总和、40.组合总和ii、131.分割回文串-爱代码爱编程
39. 组合总和
思路
回溯,同一个元素可以重复取,那调用的时候就传自己进去。数组递增,所以当加起来的和大于target就可以返回了。
代码
class Solution {
List<List<Integer>> result=new ArrayList<>();
List<Integer> path=new ArrayList<>();
int sum=0;
public List<List<Integer>> combinationSum(int[] candidates, int target) {
find(candidates,target,0);
return result;
}
public void find(int[] candidates, int target,int startIndex){
if(sum>target) return;
if(sum==target){
result.add(new ArrayList<>(path));
return;
}
for(int i=startIndex;i<candidates.length;i++){
path.add(candidates[i]);
sum+=candidates[i];
find(candidates,target,i);
path.remove(path.size()-1);
sum-=candidates[i];
}
}
}
40.组合总和II
思路
回溯,给的数组不是递增,所以要调用一下库函数排序(1.方便确认返回条件 2.可以避免取到重复组合)跟上面不一样的元素不能重复取,但是它可以提供重复元素(通过标记函数是否使用过,来剪枝。排序后,当前元素如果与前一个元素相同,并且前一个元素没有处于被使用状态,那就continue【因为我们取元素是往后取的,前一个元素没有被使用就相当于,当前元素的组合肯定和前一个元素组合相同,不是两个元素同时取的情况】)
代码
class Solution {
List<List<Integer>> result=new ArrayList<>();
List<Integer> path=new ArrayList<>();
int[] haveUsed;
int sum=0;
public List<List<Integer>> combinationSum2(int[] candidates, int target) {
haveUsed=new int[candidates.length];
Arrays.sort(candidates);
find(candidates,target,0);
return result;
}
public void find(int[] candidates, int target,int startIndex){
if(sum==target){
result.add(new ArrayList<>(path));
return;
}
for(int i=startIndex;i<candidates.length;i++){
if(sum+candidates[i]>target) break;
if(i>0 && candidates[i]==candidates[i-1] && haveUsed[i-1]==0) continue;
path.add(candidates[i]);
sum+=candidates[i];
haveUsed[i]=1;
find(candidates,target,i+1);
path.removeLast();
sum-=candidates[i];
haveUsed[i]=0;
}
}
}
131.分割回文串
思路
回溯,与上面不同的是,传的是固定的数组,但是这里传的是分割后的字符串,是一直在改变的,把startindex看作是隔板,一直划分。
代码
class Solution {
List<List<String>> result=new ArrayList<>();
List<String> pathList=new ArrayList<>();
String path="";
public List<List<String>> partition(String s) {
find(s,0);
return result;
}
public void find(String s,int startIndex){
if(startIndex>=s.length()){
result.add(new ArrayList<>(pathList));
}
for(int i=startIndex;i<s.length();i++){
int len=path.length();
path=s.substring(startIndex,i+1);
if(!charge(path)) continue;
pathList.add(path);
find(s,i+1);
pathList.remove(pathList.size()-1);
}
}
public boolean charge(String s){
int left=0;
int right=s.length()-1;
while(left<=right){
if(s.charAt(left)!=s.charAt(right)) return false;
left++;
right--;
}
return true;
}
}