【问题标题】:Another way to get all combination of integers of an array Javascript获取数组Javascript的所有整数组合的另一种方法
【发布时间】:2024-01-19 20:51:01
【问题描述】:

我想迭代一个数组并找到它们的差为 2 的所有对

这是我目前所拥有的:

var numberOfCases = 5;
var diff = 2;

var input = [1,5,3,4,2];

getPossiblepairs(input);

function getPossiblepairs(input){
    for(cmp in input){
        for(number in input){
            if((input[cmp] - input[number]) == diff){
                console.log("("+input[cmp]+","+input[number]+")");
            }
        }

    }
}

这可行,但我仍然感到内疚,因为 bigO 是 O(n^2) 使用两个 for 循环,这是唯一的方法吗?

【问题讨论】:

  • 如果你真的知道数字的分布,你可以做一些算法来变得更好(这里它们是一个连续的序列,虽然是乱序的)。但是只有 5 个条目,所以 25 次迭代 O(5^2),你真的想让它比这更有效吗?
  • 我更改了措辞以寻求其他方法,因为“最佳方法”将主要基于意见而被关闭。
  • 对 O(N) log n 的列表进行排序。与当前元素相差 2 的元素要么是下一个元素,要么是之后的元素。这是一个 O(1) 检查。检查所有这些是O(N)。所以总体 O(N log N)
  • @Paul 仅在数字不重复时才有效
  • 另一个 O(N) Pass 将相等的元素放入计数的桶中可以解决这个问题。

标签: javascript arrays performance time-complexity


【解决方案1】:

您可以在 O(n log n) 中做到这一点。对数组进行排序,然后一次通过它。找出当前元素与接下来的两个元素之间的差异,如果其中一个元素相差 2,则打印出该对。

【讨论】:

  • 他所说的。击败我一分钟
  • @Doug 我目前正在尝试实施您的解决方案,但是接下来的两个元素之间的差异不会始终保持为 1 吗?
  • 嗨@Pizzy213codes,以您的示例为例,在排序阶段之后会有[1、2、3、4、5]。第一步是比较 1 到 2 和 1 到 3。diff 在第一种情况下为 1,在第二种情况下为 2。如果有任何不连续的数字,例如 [1, 5, 7, 22],那么差异会变得更大。不过,我猜你想通了!
【解决方案2】:

这应该适用于 n log n 复杂性:

function getPossiblepairs(input, diff){
    // Create a copy of the original array, so it is not affected by the next operation
    var sortedInput = input.slice();
    // Sort the array
    sortedInput.sort();
    // Iterate through the array, starting from the 0th element
    for (var i=0, n=sortedInput.length; i<n; i++){
        firstNumber = sortedInput[i];
        // Iterate through the array, starting from the (i+1)th element
        for (var j=i+1; j<n && sortedInput[j] <= firstNumber + diff; j++){
            secondNumber = sortedInput[j];
            // if it matches, then log it!
            if (secondNumber - firstNumber == diff){
                console.log('(' + firstNumber + ', ' + secondNumber + ')');
            }
        }
    }
}

有关数组复制的更多信息,请参阅this post

使用和测试见:http://jsfiddle.net/gycjup5u/2/

【讨论】:

  • 那是 n^2 的顺序。并且在运行时比原版更糟糕(它会进行长度^2 比较,就像原版一样,但排序也是如此)
  • 是的,我的(更正的)错字完全值得“-1”。
  • 那仍然是 n^2。所以,是的,它是
  • 不,不是。第二次迭代从 i+1! 开始
  • 使用额外条件进行编辑,并将我的 -1 更改为 +1(因为您的答案确实给出了代码......)
【解决方案3】:

您有存储数组副本的内存吗?首先对其进行排序,O(n log n),然后在 O(n) 次遍历中挑选出对。

【讨论】:

    【解决方案4】:

    您可以对每个元素使用indexOf() 方法来确定数组中是否包含大于diff 给出的元素:

    function getPossiblePairs(input, diff) {
        for(i in input) {
            var n = input.indexOf(input[i] + diff);
            if(n != -1) {
                console.log("(" + input[i] + "," + input[n] + ")");
            }
        }
    }
    
    getPossiblePairs(input, diff);
    

    【讨论】:

    • 这当然是 O(N^2)。所以OP仍然会感到内疚:)
    • @Paul 是的,这是我的错,没有注意到优化请求,只是想到了另一种方法。
    最近更新 更多