Medium | LeetCode 39. 组合总和 | 回溯

39. 组合总和

给定一个无重复元素的数组 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]
]

提示:

  • 1 <= candidates.length <= 30
  • 1 <= candidates[i] <= 200
  • candidate 中的每个元素都是独一无二的。
  • 1 <= target <= 500

解体思路

本题的数组的每个数字可以使用多次, 如果是只允许使用一次, 那么此题可转化为0-1背包问题。

方法一: 回溯(暴力枚举)

class Solution {
    private List<List<Integer>> res;
    
    public List<List<Integer>> combinationSum(int[] candidates, int target) {
        res = new ArrayList<>();
        Arrays.sort(candidates);
        dfs(candidates, target, 0, new LinkedList<>());
        return res;
    }
    
    public void dfs(int[] candidates, int target, int index, LinkedList<Integer> cur) {
        // 递归出口
        if (target == 0) {
            res.add(new ArrayList<>(cur));
            return;
        }
        for (int i = index; i < candidates.length; i++) {
            // 剪枝(因为给定的数组是正整数数组)
            if (candidates[i] > target) {
                break;
            }
            // 将当前元素添加到结果当中
            cur.addLast(candidates[i]);
            // 开始递归下一个元素(由于当前元素可以多次使用)
            dfs(candidates, target - candidates[i], i, cur);
            cur.removeLast();
        }
    }
}
原文地址:https://www.cnblogs.com/chenrj97/p/14359809.html