Combination Sum

墨蓝 2023-06-09 14:30 119阅读 0赞

Combination Sum

文章目录

  • Combination Sum
    • 题目
    • 分析
    • 代码如下

题目

题目链接:https://leetcode.com/problems/combination-sum
Given a set of candidate numbers (candidates) (without duplicates) and a target number (target), find all unique combinations in candidates where the candidate numbers sums to target.

The same repeated number may be chosen from candidates unlimited number of times.

Note:

  • All numbers (including target) will be positive integers.
  • The solution set must not contain duplicate combinations.

Example 1:

  1. Input: candidates = [2,3,6,7], target = 7,
  2. A solution set is:
  3. [
  4. [7],
  5. [2,2,3]
  6. ]

Example 2:

  1. Input: candidates = [2,3,5], target = 8,
  2. A solution set is:
  3. [
  4. [2,2,2,2],
  5. [2,3,3],
  6. [3,5]
  7. ]

分析

题目给出一个包含不重复元素的int类型的数组candidates和一个目标数target。要求从candidates数组中找出所有可能的组合,这些数的和等于target每个元素可以被多次选中

可以使用递归的方法来求解这道题。

  • 首先,对给出的数组candidates进行升序排序。使用一个count数组记录每一个元素使用的次数。
  • 然后遍历整个数组(递归部分)。
    假设当前为第i个元素,为起始元素,希望得到的和为target
    求出当前元素的最大个数max = target / candidates[i]

    • 如果max <= 0,由于后面的元素大于当前元素,所以直接return
    • 否则,不断循环减少max的值,直到为0
      在每一轮循环中递归求解target = target - candidates[i] * tempi = i + 1的情况,直到i = candicates.length时停止。
  • 每次target0时,根据count数组和candidates数组,添加当前结果的最终的结果链表中。然后return(由于target0,后面的元素个数只能为0,所以直接回溯,寻找其他的情况)。

代码如下

  1. class Solution {
  2. public List<List<Integer>> combinationSum(int[] candidates, int target) {
  3. List<List<Integer>> resultLists = new ArrayList<List<Integer>>();
  4. Arrays.sort(candidates); // 排序
  5. int[] count = new int[candidates.length];
  6. combinationSum0(candidates, target, 0, count, resultLists);
  7. return resultLists;
  8. }
  9. private void combinationSum0(int[] candidates, int target, int start,
  10. int[] count, List<List<Integer>> resultLists) {
  11. if (target == 0) { // 已经完成目标
  12. addList(count, candidates, resultLists);
  13. return;
  14. }
  15. if (start >= candidates.length) { // 超出范围
  16. return;
  17. }
  18. int temp = candidates[start]; // 数组的最小值
  19. int max = target / temp; // 最多能有几个
  20. if (max <= 0) { // 最多能有0个
  21. return;
  22. }
  23. for (int i = max; i >= 0; i--) {
  24. count[start] = i;
  25. combinationSum0(candidates, target - i * temp, start + 1, count, resultLists);
  26. }
  27. // 因为会回溯,count[start]需要为0
  28. // 但是这这一步没有也没关系。
  29. // 因为在上面的循环中,i最后时0,count[start]一定会被置为0。
  30. count[start] = 0;
  31. }
  32. // 添加结果到结果链表中
  33. private void addList(int[] count, int[] candidates, List<List<Integer>> resultLists) {
  34. List<Integer> list = new ArrayList<Integer>();
  35. for (int i = 0; i < count.length; i++) {
  36. for (int j = 0; j < count[i]; j++) {
  37. list.add(candidates[i]);
  38. }
  39. }
  40. resultLists.add(list);
  41. }
  42. }

发表评论

表情:
评论列表 (有 0 条评论,119人围观)

还没有评论,来说两句吧...

相关阅读

    相关 LintCode: Combination Sum

    一个数可以使用多次 图:   节点:x(当前的和,当前要考虑的数a\[i\])   边:x->     y1(当前的和,下一个要考虑的数a\[i+1\])     y