携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第30天,点击查看活动详情
刷题的日常-2022年8月25日
一天一题,保持脑子清爽
组合总和
来自leetcode的 39 题,题意如下:
给你一个 无重复元素 的整数数组candidates 和一个目标整数target,找出candidates中可以使数字和为目标数target 的 所有不同组合 ,并以列表形式返回。你可以按 任意顺序 返回这些组合。
candidates 中的 同一个 数字可以 无限制重复被选取 。如果至少一个数字的被选数量不同,则两种组合是不同的。
对于给定的输入,保证和为target 的不同组合数少于 150 个。
示例如下:
输入:candidates = [2,3,6,7], target = 7
输出:[[2,2,3],[7]]
解释:
2 和 3 可以形成一组候选,2 + 2 + 3 = 7 。注意 2 可以使用多次。
7 也是一个候选, 7 = 7 。
仅有这两种组合。
理解题意
我们可以从题意中提取的条件如下:
- 题目给定一个数组和一个目标值
- 要求我们对数组中的数进行组合
- 如果组合出来的元素的和等于 target,将元素放进结果集
- 返回所有符合条件的组合
做题思路
组合题,用回溯就可以做,我们不断进行尝试,从前往后遍历,遍历的过程中如果能够匹配成功,加入结果集
- 进行回溯,我们可以通过排序来减少搜索次数
- 如果到结尾了也没有匹配成功,不需要操作
- 如果匹配成功,将其加入结果
- 如果出现和大于目标值,不需要进行操作
- 最后返回所有结果
代码实现
代码实现如下:
public class Solution {
public List<List<Integer>> combinationSum(int[] candidates, int target) {
Arrays.sort(candidates);
List<List<Integer>> result = new LinkedList<>();
combinationSum(candidates, 0, 0, target, result, new ArrayList<>());
return result;
}
private void combinationSum(int[] candidates, int index, int sum, int target, List<List<Integer>> result, List<Integer> item) {
if (index == candidates.length) {
return;
}
if (sum > target) {
return;
}
if (sum == target) {
result.add(item);
return;
}
ArrayList<Integer> tmp = new ArrayList<>(item);
tmp.add(candidates[index]);
combinationSum(candidates, index, sum + candidates[index], target, result, tmp);
combinationSum(candidates, index + 1, sum, target, result, item);
}
}