题目说明
给定一个无重复元素的正整数数组 candidates 和一个正整数 target ,找出 candidates 中所有可以使数字和为目标数 target 的唯一组合。
candidates 中的数字可以无限制重复被选取。如果至少一个所选数字数量不同,则两种组合是唯一的。
对于给定的输入,保证和为 target 的唯一组合数少于 150 个。
- 提示:
- 1 <= candidates.length <= 30
- 1 <= candidates[i] <= 200
- candidate 中的每个元素都是独一无二的。
- 1 <= target <= 500
示例
示例 1:
1 2
| 输入: candidates = [2,3,6,7], target = 7 输出: [[7],[2,2,3]]
|
示例 2:
1 2
| 输入: candidates = [2,3,5], target = 8 输出: [[2,2,2,2],[2,3,3],[3,5]]
|
示例 3:
1 2
| 输入: candidates = [2], target = 1 输出: []
|
笔者理解
此题是一道数组算法问题,在力扣题库中被定义为中等题。
解法
当笔者阅读完此题后,采用了回溯的办法,排序以及递归时记录上次添加位置 保证顺序选取元素,避免了元素组合的重复出现,让我们来看看具体如何实现的吧。
实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| class Solution {
public List<List<Integer>> combinationSum(int[] candidates, int target) { List<List<Integer>> result = new ArrayList<>();
List<Integer> temp = new ArrayList<>();
Arrays.sort(candidates);
dfs(result, temp, candidates, target, 0);
return result; }
public void dfs(List<List<Integer>> result, List<Integer> temp, int[] candidates, int target, int tick) { if (target == 0) { result.add(temp); return ; }
if (target < candidates[tick]) { return ; }
for (int i = tick; i < candidates.length && candidates[i] <= target; i++) { List<Integer> list = new ArrayList<>(temp); list.add(candidates[i]); dfs(result, list, candidates, target - candidates[i], i); } } }
|
时间和空间效率还行,可见此解法还比较适合此题。

总结
本题是今天的一题,难度是为中等,感兴趣的朋友都可以去尝试一下,此题还有其他更多的解法,朋友们可以自己逐一尝试。