LeetCode-15. 三数之和

58 阅读1分钟

给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0
?请你找出所有满足条件且不重复的三元组。

注意:答案中不可以包含重复的三元组。

示例:

给定数组

nums = [-1, 0, 1, 2, -1, -4]

满足要求的三元组集合为:

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

首先我想到的就是暴力解题,三重循环的那种,结果显而易见,完美无缝衔接报错,所以,接下来,仔细想想以及向大佬们的学习,最终是学会了解题的思路,有感而发,特来记载。

简述题目要求:

  • 三数求和,要求我们找到和为0的三个数的集合
  • 并且三个数不重复
  • 集合也不重复。

我们反手就是一个排序,然后我们用一个数指向排好序的数组第一个数,接着分别使用指向左边的数字l_index 和 指向右边数字r_index,每次比较sum=nums[i]+nums[l_index]+nums[r_index]和0的关系,
-----如果和大于0,说明数字大了,我们就让右索引向左移动
------ 如果和小于0,我们就让左索引向右移动,直到l_index>=r_index或者找到符合要求的元素

/**
 * @param {number[]} nums
 * @return {number[][]}
 */
var threeSum = function(nums) {
    const fin_ans=[];
    let len_num=nums.length;
    if(len_num<3||nums===null){
        return fin_ans;
    }
    nums.sort((a,b)=>a-b);//排序,非降序排列

    for(let i=0;i<len_num;i++){
        let l_index=i+1;//左指针
        let r_index=len_num-1;//右指针

//因为数组是排好序的,这里的nums[i]大于的话,sum一定大于0,也就没有进行下去的必要了,直接跳出程序
        if(nums[i]>0){
            break;
        }
        //因为题目说过,不允许有重复的数字,所以这里需要调过
        if(nums[i]===nums[i-1]){
            continue;
        }
        while(l_index<r_index)
        {
            const sum=nums[i]+nums[l_index]+nums[r_index];
            if(sum===0){
                fin_ans.push([nums[i],nums[l_index],nums[r_index]]);
                while(l_index<r_index&&nums[l_index]===nums[l_index+1]){
                    l_index++;
                }
                while(r_index>l_index&&nums[r_index]===nums[r_index-1]){
                    r_index--;
                }
                l_index++;
                r_index--;
            }
           else if(sum>0){//和大于0.就左移右指针
               r_index--;
           }
           else if(sum<0){//同上
               l_index++;
           }
        }

    }
     return fin_ans;
};