
思路:
看到所有组合,就想到回溯法。
但是普通的回溯法并不能让解集中不包括重复组合。
如candidates=[2, 3, 6, 7] ,target = 7
如果用普通的回溯法,{3, 2,2} {2,3 ,2} {2,2 ,3} 都会放入解集中。
如果每次生成一个解,就去解集中查找有没有重复的,那样时间复杂度过高。
找解集的过程可以看做四个步骤
- 找到以2开头的所有解
- 找到以3开头的所有解
- 找到以6开头的所有解
- 找到以7开头的所有解
在第2步的时候,我们需要找到以3开头的所有解,这时候解集中已经存在{2, 2, 3}了。但是如果我们再从头开始遍历candidates数组,这样2又会加入到当前的解,{3, 2,。。。} 这样就会找到{3, 2,2} ,但是和{2,2,3}就重合了,所以当我们开始找3开头的解的时候,就不能再将3以前的元素加入解中。只能从3,6,7开始遍历。
我们用一个index来记录上一趟递归已经遍历到的元素下标,然后这次循环就从当前index开始,不去考虑index之前的元素。
class Solution {
List<List<Integer>> ans = new ArrayList<List<Integer>>();
public List<List<Integer>> combinationSum(int[] candidates, int target) {
findall(candidates,target,new ArrayList<Integer>(),0);
return ans;
}
public void findall(int[] candidates, int target, ArrayList<Integer> route,int index)
{
if(target==0)
{
ans.add(new ArrayList<>(route));
return;
}
for(int i = index;i<candidates.length;i++)//每次从index开始遍历
{
if(target-candidates[i]<0)
continue;
target -= candidates[i];
route.add(candidates[i]);
findall(candidates,target,route,i);
route.remove(route.size()-1);
target += candidates[i];
}
}
}
本文探讨了一种改进的回溯算法,针对组合问题如何高效地生成不包含重复组合的解。通过设置一个index跟踪已遍历元素,确保在后续搜索时跳过已存在的组合,从而降低时间复杂度。
8万+

被折叠的 条评论
为什么被折叠?



