hot100-三数之和

127 阅读1分钟

三数之和

题目

给你一个包含n个整数的数组nums,判断nums是否存在三个元素a,b,c,使得a+b+c=0? 请找到所有和为0且不重复的三元组。 注意:答案中不可以包括重复的三元组

解读题目

用例1:

输入:nums=[-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]

就是找出每一个3元组能相加等于0,从用例可容易看出来

思路

  1. 排序 (后面去重,且为了尽量相加为0)
  2. 遍历nums数组
  • 来个特判1 如果从最小的都>0 那就不可能找到了 所以 return []
  • 来个特判2 如果排序后出现了重复,前面已经使用过了,这次不需要再尝试操作 所以 continue
  1. 两个指针 left right
  • 遍历固定一个,现在就转化为2数之和的问题了
  • 左指在固定(即当前遍历元素)的下一个
  • 右总是指在最后一个
  • 两数之和的问题 : nums[i] +left = - right (注意是-) 判定
 if(nums[i] + left < - right)  小了 left++;
 if(nums[i] + left > - right) 大了 right--;
 if(nums[i] + left == - right) 结算  left++;right--;
  1. 还要去重
  • 左重了 left一直++;
  • 右重了 right一直--;
  1. return [ ]

代码js

var threeSum = function (nums) {
// 1
  nums.sort((a, b) => a - b)
  var left, right;
  var res = []
 
 //2 
  for (let i = 0; i < nums.length; i++) {
    if (nums[0] > 0) {
      return []
    }
    if (i > 0 && nums[i] == nums[i - 1]) {
      continue
    }
  //3  
    left = i + 1;
    right = nums.length - 1
    
    while (left < right) {
      if (nums[i] + nums[left] < -nums[right]) {
        left++;
      }
      else if (nums[i] + nums[left] > -nums[right]) {
        right--;
      } else {
        res.push([nums[i], nums[left], nums[right]])
   //4  
     //去重操作
        while (left < right && nums[right] == nums[right - 1]) {
          right--;
        }
        //去重操作
        while (left < right && nums[left] == nums[left + 1]) {
          left++;
        }
        left++;
        right--;
      }
    }
  }
  //5
  return res;
};