LeetCode 👉 HOT 100 👉 组合总和 - 中等题

211 阅读2分钟

这是我参与11月更文挑战的第26天,活动详情查看:2021最后一次更文挑战

题目

给定一个无重复元素的正整数数组 candidates 和一个正整数 target ,找出 candidates 中所有可以使数字和为目标数 target 的唯一组合。

candidates 中的数字可以无限制重复被选取。如果至少一个所选数字数量不同,则两种组合是唯一的。 

对于给定的输入,保证和为 target 的唯一组合数少于 150 个。

示例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]]

思路

题目最后寻找的是所有可能不重复的组合,对于这种类型的题目,一般 回溯 算法都是比较好的解决方案。

有如下思路:

  • 先对题目所给数组 candidates 按从小到大排序

  • 定义结果数组 ans

  • 定义一个递归的函数 getCombination,接收 当前组合 Arr当前目标值 currentTarget当前索引 idx 三个参数

    • 如果 currentTarget == 0,将 Arr 放入结果数组 ans 中,进行剪枝

    • 从索引 idx 开始遍历

      • 如果 candidates[i] > currentTarget,可以进行剪枝,因为之前已经进行过排序,后面的值都会大于 currentTarget

      • 为了排除重复数据,判断 candidates[i] == candidates[i - 1] 时,跳过当前循环 continue

      • 定义下次递归的参数 newArr = [...arr, candidates[i]], newTarget = currentTarget - candidates[i], newIdx = i;

      • 进行下次递归

  • 用初始值,启动递归函数 getCombination([], target, 0)

  • 递归结束后,ans 即为所求

代码如下

    /**
     * @param {number[]} candidates
     * @param {number} target
     * @return {number[][]}
     */
    var combinationSum = function(candidates, target) {
        candidates = candidates.sort((a, b) => a - b);
        let ans = [];
        const getCombination = (arr, currentTarget, idx) => {
            if(currentTarget == 0) {
                ans.push(arr);
                return;
            }
            for(let i = idx; i < candidates.length; i++) {
                if(candidates[i] > currentTarget) {
                    return;
                }
                if(candidates[i] == candidates[i - 1]) continue;

                let newTarget = currentTarget - candidates[i];
                let newArray = [...arr, candidates[i]];

                getCombination(newArray, newTarget, i);
            }
        }
        getCombination([], target, 0);
        return ans;
    };

小结

解决问题的思路很重要,一次性想要得出所有的结果是很难做到的。但是可以通过回溯算法的思想,一步一步的列举某种答案的可能性,如果当前答案是可能的,那么继续尝试搜索答案的可能;否则就进行剪枝操作,排除不可能的答案。

LeetCode 👉 HOT 100 👉 组合总和 - 中等题

合集:LeetCode 👉 HOT 100,有空就会更新,大家多多支持,点个赞👍

如果大家有好的解法,或者发现本文理解不对的地方,欢迎留言评论 😄