16. 最接近的三数之和

65 阅读1分钟

我的回答

时间复杂度:O(n2)O(n^2)

执行用时分布
71ms
击败89.84%使用 TypeScript 的用户

消耗内存分布
52.33MB
击败81.28%使用 TypeScript 的用户

function threeSumClosest(nums: number[], target: number): number {
  //从小到大排序
  nums.sort((a, b) => a - b);

  //最左侧的定值(索引)
  let i = 0;
  let size = nums.length;

  //三数之和与target的相差
  let minDiff = Number.MAX_SAFE_INTEGER;
  let ans = 0;

  function update(v: number) {
    const sub = Math.abs(target - v);
    if (sub < minDiff) {
      ans = v;
      minDiff = sub;
    }
  }

  for (let i = 0; i < size - 2; i++) {
    //如果最小和比target大,则此值为最接近target的值
    let sum = nums[i] + nums[i + 1] + nums[i + 2];
    if (sum > target) {
      update(sum);
      break;
    }

    //如果当前定值与最大值的和比target小,则递增定值i
    sum = nums[i] + nums[size - 2] + nums[size - 1];
    if (sum < target) {
      update(sum);
      continue;
    }

    //有重复值则跳过
    if (i !== 0 && nums[i] === nums[i - 1]) {
      continue;
    }
    //左指针
    let left = i + 1;
    //右指针
    let right = size - 1;

    while (left < right) {
      let s = nums[i] + nums[left] + nums[right];
      if (s === target) {
        return s;
      }

      if (s < target) {
        update(s);
        //有重复值则跳过
        while (nums[left] === nums[++left]) {}
      } else {
        update(s);
        //有重复值则跳过
        while (nums[right] === nums[--right]) {}
      }
    }
  }
  return ans;
}

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