【问题标题】:DFS Combination Sum, How to get only unique results?DFS组合和,如何只得到唯一的结果?
【发布时间】:2021-11-14 05:58:38
【问题描述】:

我正在解决LeetCode #49 Combination Sum。我们的想法是找到总和为目标的所有唯一组合。

找到添加到总和的排列是相当简单的,但我正在努力修改我的代码以只找到唯一的排列。

动态规划中通过递归获得唯一结果的一般概念是什么?

/**
 * @param {number[]} candidates
 * @param {number} target
 * @return {number[][]}
 */
var combinationSum = function (candidates, target) {
    let distinct = []
    let dfs = (candidates, target, list = []) => {
        if (target === 0) {
            distinct.push(list)
            return
        }

        candidates.forEach((candidate, i) => {
            let diff = target - candidate;
            if (diff >= 0) {
                dfs(candidates, diff, [...list, candidate])
            }
        })
    }
    dfs(candidates, target)
    return distinct
};

输入:

[2,3,6,7]
7

我的输出:

[[2,2,3],[2,3,2],[3,2,2],[7]]

期望的输出:

[[2,2,3],[7]]

如何避免重复?

【问题讨论】:

    标签: javascript recursion dynamic-programming


    【解决方案1】:

    处理这个问题的一个简单方法是将递归分成两种情况,一种是我们使用第一个候选者,另一种是不使用。在第一种情况下,我们减少了我们需要达到的总数。其次,我们减少了可用候选人的数量。这意味着我们至少需要两个基本情况,当总数为零和候选数达到零时(这里我们还处理总数小于零的情况。)然后递归调用变得非常干净:

    const combos = (cs, t) =>
      cs .length == 0 || t < 0
        ? []
      : t == 0
        ? [[]]
      : [
          ... combos (cs, t - cs [0]) .map (sub => [cs [0], ...sub]), // use cs [0]
          ... combos (cs .slice (1), t)                               // don't use it
        ]
    
    const display = (cs, t) => 
      console .log (`combos (${JSON.stringify(cs)}, ${t}) => ${JSON.stringify(combos(cs, t))} `)
    
    display ([2, 3, 6, 7], 7)
    display ([2, 3, 5], 8)
    display ([8, 6, 7], 42)

    【讨论】:

    • 哇,漂亮的代码。
    【解决方案2】:

    您需要index 以确保不会再次重复相同的组合(不同的顺序)并从索引开始循环。

    let dfs = (candidates, target, list = [], index = 0) => {
    

    这个索引需要在你的递归函数中传递(我已将其更改为 for 循环以使其更具可读性)

     for (let i = index; i < candidates.length; i++) {
        ......
        dfs(candidates, diff, [...list, candidates[i]], i)
    

    下面的工作代码

    var combinationSum = function(candidates, target) {
      let distinct = []
      // add index in your function
      let dfs = (candidates, target, list = [], index = 0) => {
        if (target === 0) {
          distinct.push(list)
          return
        }
    
        for (let i = index; i < candidates.length; i++) {
          let diff = target - candidates[i];
          if (diff >= 0) {
            //pass index as your current iteration
            dfs(candidates, diff, [...list, candidates[i]], i)
          }
        }
      }
      dfs(candidates, target)
      console.log(distinct);
    };
    
    
    combinationSum([2, 3, 6, 7], 7);

    【讨论】:

      猜你喜欢
      • 2021-07-01
      • 1970-01-01
      • 2021-06-29
      • 2018-06-01
      • 1970-01-01
      • 1970-01-01
      • 2022-12-28
      • 2018-05-13
      • 1970-01-01
      相关资源
      最近更新 更多