执行结果:
通过
显示详情
执行用时 :3 ms, 在所有 Java 提交中击败了98.06% 的用户
内存消耗 :36.9 MB, 在所有 Java 提交中击败了91.67%的用户
回溯法框架:(这个框架是labuladong写的 回溯框架!!!)
1、路径:也就是已经做出的选择。
2、选择列表:也就是你当前可以做的选择。
3、结束条件:也就是到达决策树底层,无法再做选择的条件。
代码方面,回溯算法的框架:
result = []
def backtrack(路径, 选择列表):
if 满足结束条件:
result.add(路径)
return
for 选择 in 选择列表:
做选择
backtrack(路径, 选择列表)
撤销选择
其核心就是 for 循环里面的递归,在递归调用之前「做选择」,在递归调用之后「撤销选择」,特别简单。
题目:
给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
candidates 中的数字可以无限制重复被选取。
说明:
所有数字(包括 target)都是正整数。
解集不能包含重复的组合。
示例 1:
输入: candidates = [2,3,6,7], target = 7,
所求解集为:
[
[7],
[2,2,3]
]
示例 2:
输入: candidates = [2,3,5], target = 8,
所求解集为:
[
[2,2,2,2],
[2,3,3],
[3,5]
]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/combination-sum
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路:
利用回溯法
代码:
class Solution {
List<List<Integer>> result=new LinkedList<>();
public List<List<Integer>> combinationSum(int[] candidates, int target) {
//candidates是选择列表
//target是目标值,随题目的变化而变化
//track是路径
//每次从start开始是为了从小的开始取值,避免重复
LinkedList<Integer> track=new LinkedList<>();
Arrays.sort(candidates);
backtrack(candidates,0,target,track);
return result;
}
public void backtrack(int[] candidates,int start,int target,LinkedList<Integer> track)
{
//这种情况说明已经找到了
if(target==0)
{
result.add(new LinkedList<>(track));
return;
}
for(int i=start;i<candidates.length;i++)
{
//这种情况说明此条路径不存在了,不用继续往下循环了,往下循环也是不存在的
if(target<candidates[i])
{
break;
}
//回溯法的精髓部分
track.add(candidates[i]);
backtrack(candidates,i,target-candidates[i],track);
track.removeLast();
}
}
}