15. 三数之和 JavaScript实现

244 阅读1分钟

三数之和

一、暴力法

如果利用三层fo循环去找所有满足条件的元组,则会出现相同的元素列表。比如[1,-1,0] 和 [-1,1,0]。这就需要再次进行去重操作,时间复杂度很大O(n3)。

二、双指针 + 排序

详解 在这里插入图片描述 问题1 : 如何去重? 这里有两个地方进行去重操作,一个是遍历元素的时候,一个是移动指针的时候。两个地方都要考虑到

问题2:双指针如何设置更加方便? 见代码

var threeSum = function(nums) {
    // 长度是常数
    const n = nums.length;
    let result = [];


    // 当元素少于3的时候,返回空
    if(nums == null || n < 3) return result;

    // 元素进行升序排列,这样可以根据相加结果进行移动.注意js中sort的写法
    nums.sort((a,b) => a - b);

    // 第一个值大于0,可以不考虑
    if (nums[0] > 0) return result;


    // i指向当前元素(固定),进行遍历。L指向下一个元素,R指向最后一个元素。每次循环根据相加结果分别移动L和R
    for(let i=0;i<n;i++){
        // 进行第一次去重操作,判断i当前元素是否重复。重复就结束这次循环,开启下一次循环。
        if (i > 0 && nums[i] == nums[i-1]) continue;

        let L = i + 1;
        let R = n - 1;

        while(L < R){
            const sum = nums[i] + nums[L] + nums[R];
            // 和为0时
            if(sum == 0){
                result.push([nums[i],nums[L],nums[R]]);

                // 第二次去重操作。当和为0的时候,防止L和R的重复元素出现
                while(L < R && nums[L] == nums[L+1]) L++;
                while(L < R && nums[R] == nums[R-1]) R--;

                // 和为0,移动L和R指针
                L++;
                R--;
            }

            // 和不为0,移动L和R,使得和为0.
            // 大于0,代表大于0的值太大了,需要调小
            else if(sum > 0) R--;
            else if(sum < 0) L++;
        }
    }
    return result;
};

三、js中基础知识

1、元素排序sort

// sort需要自定义排序方法
nums.sort((a,b) => a - b);

2、短语句的写法

// 常规写法
if(n > 3){
	return [];
}

// 简洁写法
if(n > 3) return [];