双指针|三数之和

📋目录

     ✅ 15.三数之和

    

 15.三数之和

⏰ 1.解题思路

  • 题目要求最后的结果不能有重复的,使用哈希法要考虑最后的结果去重,很容易超时。
  • 所以直接使用双指针法,具体思路是
    • 先将数组进行排序,从小到大
    • 最外层是一个for循环,从i下标为0 的地方开始,并且定义一个left在下标为i+1,定义下标为数组结尾为right
    • 如果 nums[i] + nums[left] + nums[right] < 0 说明 此时 三数之和小了,left 就向右移动,才能让三数之和大一些,直到left与right相遇为止。
  • 第一个数a = nums[i] 的去重,因为在for循环里面,所以可以直接跳过,怎么跳过呢?还要考虑一个问题是先跟下一个数比较,发现重复之后跳过还是先跳到下一个,回过头来根上一个数比较是否有重复。二者的区别就在于如过遇到下面这种数组
//通俗讲,先判断了再决定要不要跳过
if (nums[i] == nums[i+1]){
    continue
}
//如果数组为[-1,-1,2],当遍历第一个数为-1,有判断下一个数为-1,那么这个数组就直接被pass掉,实际上,这个数组是符合规范

//正确写法是
if (nums[i] == nums[i-1]){
    continue
}

//主要是要这个数组的和在为 0 的同时,三元组不能重复,但是里面的元素可以重复[0,0,0]

💻 2.代码


 var threeSum = function(nums){
    const res = [],len = nums.length
    //数组排序从小到大
    nums.sort((a,b)=>a-b)
    for(let i = 0;i<nums.len;i++){
        let iNum = num[i],l = i+1, r=len -1
        //数组排过序,如果第一个大于0直接返回res
        if (iNum > 0) return res;
        //去重
        if ( iNum == nums[i-1]) continue
        while(lef<right){
            let lNum = nums[l],rNum = nums[r],threeSum = iNum + lNum +rNum
            //如果三数之和小于0,则左指针往右
            if(threeSum < 0) l++
            else if (threeSum > 0) r--
            else{
                res.push([iNum,lNum,rNum])
                //去重
                while(l < r && nums[l] == nums[l+1]) {
                    l++
                }
                while(l < r && nums[r] == nums[r-1]){
                    r--
                }
                l++
                r--
            }

        }

    }

 }

 

 

 

 

posted @ 2023-06-02 18:05  karen哈哈哈  阅读(68)  评论(0编辑  收藏  举报