在JavaScript中将O(n ^ 3)更改为O(n ^ 2)

前端之家收集整理的这篇文章主要介绍了在JavaScript中将O(n ^ 3)更改为O(n ^ 2)前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
参见英文答案 > Finding three elements in an array whose sum is closest to a given number13个
我正试着在编码解决方案中节省时间.

我有一个名为tripletSum的函数,它接受两个参数x和a,其中x是数字,a是数组.

如果列表a包含三个加起来为x的元素,则该函数应返回true,否则返回false.

我创建了以下工作解决方案:

function tripletSum(x,a) {
    for(var i = 0; i < a.length; i++) {
        for(var j = i + 1; j < a.length; j++) {
            for(var k = j + 1; k < a.length; k++) {
                if((a[i] + a[j] + a[k]) === x) {
                    return true;
                }
            }
        }
    }
    return false;
}

但这似乎不是最好的做法.目前运行此函数所需的时间是O(n ^ 3),如果我没有弄错,我认为可以改进O(n ^ 2)的时间复杂度.

无论如何,我可以改变这个代码来做到这一点?

编辑:这不是另一个问题的重复,因为我要求对我当前在JavaScript中的示例进行具体改进,这不是它在标记的重复问题中提出的要求.

解决方法

这是一个想法:首先需要对数组进行排序.之后,您可以有一个循环遍历从0到N-2(排他性)的所有元素.让我们称之为这个循环的索引.这就是数组排序的有用之处.我们将使用数组排序的知识来“挤压”“未处理的”子阵列(范围从i 1到第N个元素).您现在将左右两个值. left将指示未处理子数组的左索引,而right将指示数组未处理部分的正确索引.在开始时我们设置left = i 1和right = N – 1.我们计算总和a [i] a [left] a [right].现在我们有3个案例:

>如果sum = x则返回true
>如果总和> x然后我们需要降低总和,所以我们需要递减1(从右边挤压)
>如果总和< x然后我们需要使总和更大,所以我们需要向左递增1(从左边挤压)
以下是Javascript解决方案.

function tripletSum(x,a) {
    a.sort(function(i,j) {
        return i - j;
    });

    var N = a.length;

    for(var i = 0; i < N - 2; i++) {
        var left = i + 1,right = N - 1;

        while(left < right) {
            var sum = a[i] + a[left] + a[right];
            if(sum === x) {
                return true;
            }
            else if(sum > x) {
                right--;
            }
            else {
                left++;
            }
        }

    }

    return false;
}

时间复杂度为O(N ^ 2),并且没有使用额外的空间.

猜你在找的JavaScript相关文章