15. 三数之和 ,比较详细的解释

48 阅读1分钟
function threeSum(nums: number[]): number[][] {
  //从小到大进行排序
  nums.sort((a, b) => a - b);

  let size = nums.length;
  //  定义二维数组
  const resNums: number[][] = [];
  //  nums[0] > 0: 如果最小的值都大于0,则结果必然不等于0,return[]
  //  nums[size - 1] < 0: 如果最大的值都小于0,则结果必然不等于0,return[]
  if (nums[0] > 0 || nums[size - 1] < 0) return [];

  let i = 0; //i为最左侧定值,移动其右侧的first指针,和last指针

  //i < size - 2:让i右侧留两个位置,给first和last
  //nums[i] <= 0: 由于nums[i]为当前计算的最左侧值,所以如果这个值大于0,则结果必然大于0
  while (i < size - 2 && nums[i] <= 0) {
    let first = i + 1; //i右侧的左指针
    let last = size - 1; //i右侧的右指针

    //nums[i] * nums[last] > 0: 证明 两者都是相同符号(- 或 +)
    //而 nums[i]为定值,也是最小值,如果它为 +(大于0) ,则结果必然 >0
    //而 nums[last],如果它为 -(小于0) ,则结果必然 < 0
    while (first < last) {
      if (nums[i] * nums[last] > 0) break;

      const sum = nums[i] + nums[first] + nums[last];

      if (sum === 0) {
        resNums.push([nums[i], nums[first], nums[last]]);
      }
      if (sum <= 0) {
        // 递增左指针first,并保证下一个值 !== 上一个值
        while (nums[first] === nums[++first]) {}
      } else {
        // 递减右指针last,并保证下一个值 !== 上一个值
        while (nums[last] === nums[--last]) {}
      }
    }

    // 递增i,并保证下一个值 !== 上一个值
    while (nums[i] === nums[++i]) {}
  }
  return resNums;
}

console.log(threeSum([-1, 0, 1, 2, -1, -4]));