39 力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
和力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台不同的地方在于,这个题允许有重复。所以两者的树的差别即为:
即一个每次从i+1开始,一个每次从i开始。
class Solution {
List<List<Integer>> result = new ArrayList<>();
List<Integer> list = 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 startIndex,int sum){
if(sum == target){
result.add(new ArrayList<>(list));
return;
}
if(sum > target){
return;
}
for(int i = startIndex; i < candidates.length;i++){
sum = sum + candidates[i];
list.add(candidates[i]);
backtracking(candidates,target,i,sum);
list.remove(list.size() - 1);
sum = sum - candidates[i];
}
}
}
40力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
这道题的关键在于,如何去重。比如[10,1,2,7,6,1,5]这个数组,target= 8,那么[1,1,6]满足要求,[1,7]、[1,2,5]满足要求但是只能出现一次。如果用常规的组合问题的遍历思想,那么会出现两次:[1,7]、[1,2,5]、[1,7]、[1,2,5]。这时需要去重,而且不能把[1,1,6]过滤掉。
用一个全为0的数组used表示candidates数组里的各索引的数有没有被用到。对于[1,7]、[1,2,5]这种的,需要先对数组candidates进行排序,这样就使相等的元素排列在一起。对于两个相同的元素,第一个元素、第二个元素如果都被用到了是符合条件的([1,1,6]),只有第一个元素没被用到,第二个元素被用到了放弃这次组合(因为第二个元素开始的所有排序,第一个元素都已经试过了)
class Solution {
List<List<Integer>> result = new ArrayList<>();
ArrayList<Integer> list = new ArrayList<>();
public List<List<Integer>> combinationSum2(int[] candidates, int target) {
int[] used = new int[candidates.length];
Arrays.sort(candidates);
backtracking(candidates,target,0,0,used);
return result;
}
public void backtracking(int[] candidates, int target,int startIndex,int sum,int[] used){
if(sum == target){
result.add(new ArrayList<>(list));
return;
}
if(sum > target){
return;
}
for(int i = startIndex;i < candidates.length; i++){
if(i > 0 && candidates[i] == candidates[i-1] && used[i-1] == 0){
continue;
}
list.add(candidates[i]);
sum = sum + candidates[i];
used[i] = 1;
backtracking(candidates,target,i+1,sum,used);
sum = sum - candidates[i];
list.remove(list.size() - 1);
used[i] = 0;
}
}
}
131.力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
这个题重点是怎么模拟分割字符串的过程,由图不难看出,startIndex 可以模拟
class Solution {
List<List<String>> result = new ArrayList<>();
ArrayList<String> list = new ArrayList<>();
public List<List<String>> partition(String s) {
backtracking(s,0);
return result;
}
public void backtracking(String s,int startIndex){
if(startIndex == s.length()){
result.add(new ArrayList<>(list));
return;
}
for(int i = startIndex; i < s.length(); i++){
if(isHuiWen(s.substring(startIndex,i+1))){
list.add(s.substring(startIndex,i+1));
}else{
continue;
}
backtracking(s,i+1);
list.remove(list.size() - 1);
}
}
public boolean isHuiWen(String s){
for(int i = 0,j = s.length() - 1; i < j ;i++,j--){
if(s.charAt(i) != s.charAt(j)){
return false;
}
}
return true;
}
}