leetcode 3sum help,我该如何优化这个答案?

时间:2018-06-03 21:33:45

标签: javascript algorithm

我有一个似乎通过大多数测试的解决方案,但速度太慢。如果我没有弄错的话,由于三个for循环,复杂度为O(n ^ 3)。

我的想法是从i,j和k处的数组的前三个位置开始,将它们相加,看看它是否加起来为0.

功能目标是:

给定n个整数的数组nums,nums中是否有元素a,b,c,a + b + c = 0?找到数组中所有唯一的三元组,它们总和为零。

注意: 解决方案集不得包含重复的三元组。

示例: 给定数组nums = [-1, 0, 1, 2, -1, -4]

解决方案集是:

[
  [-1, 0, 1],
  [-1, -1, 2]
]

var threeSum = function(nums) {
    var originalArray = nums
    var lengthArray = nums.length
    
    //sort array smallest to largest
    nums.sort(function(a,b) {
        return a-b
    })
    
    function arrayEqual(array1, array2){
        
        var equal = false
        array1.forEach((value1) => {
            if(array1 === array2){
                
                equal = true
            }
        })
        return equal
    }
    
    var sum = 0;
    var answerArray = [];
    //start from first digit and add from there
    for(var i = 0; i<lengthArray; i++){
        for(var j = i+1; j<lengthArray; j++){
            for(var k = j+1; k<lengthArray; k++){
                if((nums[i]+nums[j]+nums[k] === 0)){
                    if(!arrayEqual(answerArray, [nums[i],nums[j],nums[k]])){
                        answerArray.push([nums[i],nums[j],nums[k]])
                    }
                }
            }
        }
    }
    
    return Array.from(new Set(answerArray.map(JSON.stringify)), JSON.parse)
};

如何使用三个for循环来完成这项工作(又如何优化此解决方案?)

2 个答案:

答案 0 :(得分:2)

以这种方式思考这个问题。从数组中选择任意数字k。现在,您需要在数组中找到另外两个添加到-k的数字。得到的三个数字之和为k + (-k) = 0

所以这个问题减少了,在数组中找到两个数字,如果给定的数组被排序,则使用两个指针方法将O(n)添加到给定的数字。

简而言之,对数组进行排序,逐个获取每个数字(k)(O(n)),找到另外两个数字,其中总和为-k (O(n))

总时间复杂度:O(n)* O(n)= O(n 2

答案 1 :(得分:1)

您可以在O(n^2)的运行时中解决问题。这是使用JavaScript的解决方案

    var threeSum = function(nums) {
    var solutions = [];
    var target = 0;
    nums.sort(function(a, b) {
        return a - b;
    });
    for(var i = 0; i < nums.length - 2; i++) {
        if(i === 0 || (i > 0 && nums[i] !== nums[i - 1])) {
        var lo = i + 1;
        var hi = nums.length - 1;
        var sum = - nums[i];
        while(lo < hi) {
            if(nums[lo] + nums[hi] === sum) {
                solutions.push([nums[i],nums[lo],nums[hi]]);
                while (lo < hi && nums[lo] === nums[lo + 1]) lo++;
                while (lo < hi && nums[hi] == nums[hi-1]) hi--;
                lo++; hi--;
            }else if (nums[lo] + nums[hi] > sum) {
                hi--;
            }else {
                lo++;
            }
        }
        }
};
    return solutions;
}