39. 组合总和
题目地址: https://leetcode-cn.com/problems/combination-sum/
题目描述: 给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
说明:
- candidates 中的数字可以无限制重复被选取。
- 所有数字(包括 target)都是正整数。
- 解集不能包含重复的组合。
思路
回溯算法居然有模板可以套用,真的是太好用了。
result = []
def backtrack(路径, 选择列表):
if 满足结束条件:
result.add(路径)
return
for 选择 in 选择列表:
做选择
backtrack(路径, 选择列表)
撤销选择
代码
class Solution {
public List<List<Integer>> combinationSum(int[] candidates, int target) {
List<List<Integer>> result = new ArrayList();
//先排序,便于后面剪枝
Arrays.sort(candidates);
dfs(candidates, target, 0, new ArrayList(), result);
return result;
}
/**
* @param nums 原数组
* @param val 剩余数值
* @param start 选择区域,起点
* @param path 选择列表
* @param result 结果集
*/
void dfs(int[] nums, int val, int start, List<Integer> path, List<List<Integer>> result){
if(val == 0){ //找到
List<Integer> tmp = new ArrayList(path.size());
for(Integer i: path){
tmp.add(i);
}
result.add(tmp);
return;
}
for(int i=start;i < nums.length; i++){
int v = nums[i];
if(v > val){//前面已经排序了,这里就可以直接跳过
break;
}
//做选择
path.add(v);
dfs(nums, val - v, i, path, result);
//撤销选择
path.remove(path.size() -1 );
}
}
}