40. 组合总和 II回溯Normal

Posted pre_eminent

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了40. 组合总和 II回溯Normal相关的知识,希望对你有一定的参考价值。

40. 组合总和 II

难度中等

给你一个由候选元素组成的集合 candidates 和一个目标数 target ,

找出 candidates 中所有可以使数字和为 target 的组合。

candidates 中的每个元素在每个组合中只能使用 一次 。

注意:解集不能包含重复的组合。 


示例 1:

输入: candidates = [10,1,2,7,6,1,5], target = 8,
输出:
[
[1,1,6],
[1,2,5],
[1,7],
[2,6]
]

示例 2:

输入: candidates = [2,5,2,1,2], target = 5,
输出:
[
[1,2,2],
[5]
]

提示:

  • 1 <= candidates.length <= 100
  • 1 <= candidates[i] <= 50
  • 1 <= target <= 30

思路

1. 与39.组合总和不同的是,每一个元素只能用一次

2. 与39.组合总和相同的是,结果集中不能有重复的

3. 在回溯前,必须先排序

4. 在回溯中,每一个元素只能选 或者 不选

5. 如果是不选,那么它身后和它相邻的同样的数字要全部跳过(防止重复结果)

6. 并且选的情形要放在前面,不选的情形放后面


解答:

/**
 * @param number[] choiceArr
 * @param number target
 * @return number[][]
 */

var combinationSum2 = function(choiceArr, target) 
    // 必须先排序(会有相同的数字)
    choiceArr.sort((a,b)=>return a-b;);

    let res = [];
    let path = [];

    // 重点:相同的数字不能重复选取
    backtrack(0, target, choiceArr, path, res);

    return res;
;

function backtrack(currentIndex, target, choiceArr, path, res) 
    // 结束条件有两种情况
    // 1. target == 0了,即找到组合方法了
    if (target === 0) 
        // 注意js 数组共用内存
        let pathCopy = [...path];
        res.push(pathCopy);
        return;
    

    // 2. currentIndex 已经到choiceArr末尾了
    if (currentIndex === choiceArr.length) 
        return;
    

    // 对于当前选项,
    // 有两种情况:采用 或者 不采用
    let currentChoice = choiceArr[currentIndex];

    // 1. 必须先采用当前的数字,
    // 前提是:剩余空间还足够时
    let newTarget = target - currentChoice;

    if (newTarget >= 0) 
        // 做出选择
        path.push(currentChoice);

        // 进入下一层
        backtrack(currentIndex + 1, newTarget, choiceArr, path, res);

        // 撤销刚才的选择
        path.pop();
    
    
    // 2.然后才是  不使用当前的数字,
    // 直接进入下一层
    // 进入下一层之前,必须要跳过所有与它相同的数字(因为已经决定 不采用该数字了)
    while(currentIndex < choiceArr.length && choiceArr[currentIndex] === currentChoice)
      currentIndex++;
    

    backtrack(currentIndex, target, choiceArr, path, res);


 

以上是关于40. 组合总和 II回溯Normal的主要内容,如果未能解决你的问题,请参考以下文章

leetcode 40. 组合总和 II---回溯篇3

代码随想录|day26|回溯算法part03● 39. 组合总和● 40.组合总和II● 131.分割回文串

递归与回溯7:LeetCode40. 组合总和 II(不可重复)

216. 组合总和 III-----回溯篇4

[leetcode 40. 组合总和 II] 不排序使用哈希表+dfs递归 vs 排序栈+回溯

113. 路径总和 II回溯Normal