【问题标题】:How can I find all the correct combinations?我怎样才能找到所有正确的组合?
【发布时间】:2021-10-31 22:17:02
【问题描述】:

会有一个数组和一个数字

我想按数字从 array 中获取所有可能的组合。 我的意思是如果数组是 [2,4,1,3,0,1] 并且数字是 5, 那么结果将是 [2,3] [4,1] [2,3,0] [4,1,0] [1,3,1,0]。

所以,我试试这个算法

function solution(arr, n) {
  let result = []
  for (let i = 0; i < arr.length; i++) {
    for (let j = i + 1; j < arr.length; j++) {
       let sum = arr[i] + arr[j]
       if(sum === n) {
           result.push([arr[i], arr[j]])
       }
    }
  }
  return  result
}

但是,此算法仅适用于两种组合。 最近五个小时,我一直在想怎么做三个组合和四个组合。

有什么方法可以访问它来解决这个问题?

【问题讨论】:

  • 听起来像臭名昭著的子集和问题
  • 简单的蛮力方法是遍历所有 2^N 个可能的组合并检查总和。
  • 数组中会只有正数吗?
  • @RickardElimää:样本中有一个零。
  • 好的,我重新提出这个问题。 :) 数组中会有负数吗?

标签: javascript algorithm combinations


【解决方案1】:

你可以尝试一些简单而幼稚的事情:

const sumsTo = ([n, ...ns], t) =>
  n === undefined ? [] : [                         // if list is empty, no results
    ... (n === t ? [[n]] : []),                    // if n == t, include [n]
    ... sumsTo (ns, t - n) .map (s => [n, ...s]),  // include n and recur
    ... sumsTo (ns, t)                             // skip n and recur
  ]

console .log (
  sumsTo ([2, 4, 1, 3, 0, 1], 5)
  /* display */ .map (JSON.stringify) .join ('\n')
)
.as-console-wrapper {max-height: 100% !important; top: 0}

这里我们使用了一个相当简单的递归,总是减少要测试的数字列表,有时还会减少我们正在寻找的总数。

它将重复数组,例如在本例中,[4, 1]。如果要删除重复项,我们可以对结果运行唯一性函数(例如const uniq = (xs) =&gt; [...new Set(xs)])。

性能可能很糟糕,但似乎这里没有算法会有很好的性能。

【讨论】:

    【解决方案2】:

    解决问题的一种优雅方法是使用稍微修改的 k 组合算法。

    我没有足够的 JavaScript 知识来用你的母语编写它,但这里有一个 Python 实现,我希望它和伪代码一样足够:

    def find_combination(input, value):
        """Find all combination in input which it's sum is equal to value and has minimum of two elements."""
        
        for k in range(2, len(input) + 1):
            result = gen_combination(input, k, value)
            for x in result:
                print(x)
    
    
    def gen_combination(input, k, value):
        """Returns unique combinations of k-value from input which it's sum equal to value."""
    
        output = []
        _gen_combination_rec(input, output, k, value)
        return output
    
    
    def _gen_combination_rec(array, output, k, value, index=0, data=None):
        """Recursively traverse input to find combinations of k-value."""
    
        if data == None:
            data = [0] * k
    
        if index == k:
            sd = sorted(data)
            if sd not in output and sum(data) == value:
                output.append(sd)
            data[index - 1] = 0
            return
    
        i = 0
        n = len(array)
        while i < n and index < k:
            data[index] = array[i]
            _gen_combination_rec(array[i + 1 :], output, k, value, index + 1, data)
            i += 1
    
    
    if __name__ == "__main__":
        input = [2, 4, 1, 0, 3, 1]
        find_combination(input, 5)
    
    

    这是从终端运行时上述代码的输出:

    $ python main.py 
    [2, 3]
    [1, 4]
    [0, 2, 3]
    [0, 1, 4]
    [1, 1, 3]
    [0, 1, 1, 3]
    

    【讨论】:

    • I have translated your algorithm to JavaScript。唯一的主要区别是 JS 没有很好的 sd in data 等价物。我创建了isIn(),但它尽可能简单。它可能效率不高,因为它每次都必须重新扫描阵列。它可以改进,但我会将其作为练习留给其他人,因为有多种优化路径可供选择,而我不想承诺其中一种。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-22
    • 2012-11-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多