双指针,

首先将num数组进行排序

然后依次取出数组的每一个元素,找到另外两个元素的和为-num[i],采用双指针的做法

left = i+1; right = n-1; target = -num[i]

  • 和小于target,left++
  • 和大于target,right--,
  • 和等于target时,加入到结果数组,注意去重,同时注意边界条件,找到与加入结果数组left值不同的元素,right同理

注意:一开始也要去重,判断条件i!=0 && num[i] == num[i-1],为什么不可以是num[i]==num[i+1]呢?

例子:[-10,-10,-10,20,20,20]

假设目标值是-20,如果采用num[i]==num[i+1]的判断条件,则第一个和第二个-10均会continue,从而找不到-20, 然而-10和-10的组合可以得到-20

function threeSum( num ) {
  
  if(num.length<3)
    return [];
  
  num = num.sort((a,b)=>a-b);//排序
  let ans = [];
  let n = num.length;
  for(let i=0; i<n-2; i++){
    if(i!=0 &&  num[i] == num[i-1])
      continue;
    let left = i+1;
    let right = n-1;
    let target = -num[i];
    while(left<right){
      if(num[left] + num[right] < target)
        left++;
      else if(num[left] + num[right] > target)
        right--;
      else{//等于的情况
        ans.push( [ num[i],num[left],num[right] ] );
        while(left+1<right && num[left]==num[left+1])  left++;
        while(left<right-1 && num[right]==num[right-1])  right--;
        left++;
        right--;
      }
    }
  }
  return ans;