核心思想:深度优先遍历DFS
未剪枝的全排列:
可以发现,为0的叶子节点有重复的。
为了克服上述问题,我们可以将输入数组先排序,这样就越减越负的厉害的想法,用begin变量卡住,使得本节点不使用同一层节点的前面的节点用过的值,保证不重复。
剪枝后的全排列:
class Solution {
public List<List<Integer>> combinationSum(int[] candidates, int target) {
int len = candidates.length;
Deque<Integer> deque = new LinkedList<>();
List<List<Integer>> list = new ArrayList<>();
Arrays.sort(candidates);
dfs(candidates,target,0,len,deque,list);
return list;
}
public void dfs(int[] candidates,int target, int begin, int end, Deque<Integer> deque, List<List<Integer>> list){
if(target == 0){
list.add(new ArrayList<>(deque));
return;
}
//这里的i = begin很关键,使得不再重复
for(int i = begin; i < end; i++){
//剪枝
//if放在for里能够使得负数不再继续循环
if(target - candidates[i] < 0){
return;
}
deque.offerLast(candidates[i]);
dfs(candidates,target - candidates[i],i,end,deque,list);
deque.pollLast();
}
}
}
图片参考自LeetCode的帅气的作者:liweiwei1419