40. 组合总和 II
class Solution {
List<List<Integer>> res=new ArrayList<>();
List<Integer> path=new ArrayList<>();
public List<List<Integer>> combinationSum2(int[] candidates, int target) {
//未理解这里的去重逻辑,在于相同的数只能让其在不同层级上组合,而不能在同一层上出现
//别忘记排序
Arrays.sort(candidates);
backtracking(candidates,target,0);
return res;
}
public void backtracking(int[] candidates,int target,int index){
if(target==0){
res.add(new ArrayList<>(path));
return;
}
if(target<0){
return;
}
for(int i=index;i<candidates.length;i++){
//避免同一层元素出现重复的情况
if(i>index && candidates[i]==candidates[i-1]){
continue;
}
target-=candidates[i];
path.add(candidates[i]);
backtracking(candidates,target,i+1);
target+=candidates[i];
path.remove(path.size()-1);
}
}
}
131. 分割回文串
class Solution {
List<List<String>> res = new ArrayList<>();
List<String> path = new ArrayList<>();
public List<List<String>> partition(String s) {
backtracking(s,0);
return res;
}
public void backtracking(String s,int index){
if(index==s.length()){
res.add(new ArrayList<>(path));
return;
}
for(int i=index;i<s.length();i++){
if(ishw(s,index,i)){
path.add(s.substring(index,i+1));
backtracking(s,i+1);
path.remove(path.size()-1);
}
else{
continue;
}
}
}
public boolean ishw(String s,int index,int i){
while(i>index){
if(s.charAt(i)!=s.charAt(index)){
return false;
}
i--;
index++;
}
return true;
}
}
78. 子集
class Solution {
List<List<Integer>> res=new ArrayList<>();
List<Integer> path=new ArrayList<>();
public List<List<Integer>> subsets(int[] nums) {
backtracking(nums,0);
return res;
}
public void backtracking(int[] nums,int index){
res.add(new ArrayList<>(path));
for(int i=index;i<nums.length;i++){
path.add(nums[i]);
backtracking(nums,i+1);
path.remove(path.size()-1);
}
}
}
90. 子集 II
class Solution {
List<List<Integer>> res=new ArrayList<>();
List<Integer> list=new ArrayList<>();
public List<List<Integer>> subsetsWithDup(int[] nums) {
Arrays.sort(nums);
backtracking(nums,0);
return res;
}
public void backtracking(int[] nums,int index){
res.add(new ArrayList<>(list));
for(int i=index;i<nums.length;i++){
//和40题的约束条件有异曲同工之妙,确保同层不会重复,而不同层元素可重复。
if(i>index && nums[i]==nums[i-1]){
continue;
}
list.add(nums[i]);
backtracking(nums,i+1);
list.remove(list.size()-1);
}
}
}
491. 递增子序列
错误思路:
错误原因:
因为求递增序列不能对数组排序,所以判断条件
if(i>index&&nums[i]==nums[i-1] || path.size()!=0&&nums[i]<path.get(path.size()-1)){
不能达到每一层都确保只有一个数保留的结果
eg:[1,2,3,1,1,1,1]
class Solution {
List<List<Integer>> res=new ArrayList<>();
List<Integer> path=new ArrayList<>();
public List<List<Integer>> findSubsequences(int[] nums) {
backtracking(nums,0);
return res;
}
public void backtracking(int[] nums,int index){
if(path.size()>=2){
res.add(new ArrayList<>(path));
//不能return,要继续搜索
//return ;
}
for(int i=index;i<nums.length;i++){
if(i>index&&nums[i]==nums[i-1] || path.size()!=0&&nums[i]<path.get(path.size()-1)){
continue;
}
// if(nums[i]>=nums[i-1]){
path.add(nums[i]);
backtracking(nums,i+1);
path.remove(path.size()-1);
//}
}
}
}
正确做法
491. 递增子序列
class Solution {
List<List<Integer>> res=new ArrayList<>();
List<Integer> path=new ArrayList<>();
public List<List<Integer>> findSubsequences(int[] nums) {
int[] used=new int[201];
backtracking(nums,0,used);
return res;
}
public void backtracking(int[] nums,int index,int[] used){
if(path.size()>1){
res.add(new ArrayList<>(path));
}
used = new int[201];
for(int i=index;i<nums.length;i++){
if(used[nums[i]+100]==1 || path.size()!=0&&nums[i]<path.get(path.size()-1)){
continue;
}
path.add(nums[i]);
used[nums[i]+100]=1;
backtracking(nums,i+1,used);
path.remove(path.size()-1);
//由于前面的 used = new int[201];,下一层自动清零
// used[nums[i]+100]=0;
}
}
}