一、双指针法——C语言实现

/** * 最靠近的三数和  * LeetCode第16题 * author: aliao   language: C*/#include <stdio.h>#include <stdlib.h>int compare (const void *a, const void *b) {  return (*(int *)a) - (*(int *)b);}int threeSumClosest(int *nums, int numsSize, int target){  // 先给数组升序排序  qsort(nums, numsSize, sizeof(int), compare);   // 定义返回值  int best;  for (int i = 0; i < numsSize; i++)  {    if (i > 0 && nums[i] == nums[i - 1]) {      continue;    }    int head = i + 1;    int tail = numsSize - 1;    while (head < tail)    {      // 求和      int sum = nums[i] + nums[head] + nums[tail];      // 将第一个三数之和存为最靠近解best      if (i == 0 && head == 1 && tail == numsSize - 1)      {        best = sum;      }      // 更新三元素之和      if (abs(sum - target) < abs(best - target)) {        best = sum;       }      if (sum < target) {        // 左指针左移        head++;        // 左指针去重        while (nums[head] == nums[head - 1])        {          head++;        }      } else if (sum > target) {        // 右指针左移        tail--;        // 右指针去重        while (nums[tail] == nums[tail + 1])        {          tail--;        }      } else {        return target;      }    }  }  return best;}int main (void)  {  int nums[] = {-1, 2, 1, -4};  int numsSize = 4;  int target = 1;  printf("%d\n", threeSumClosest(nums, numsSize, target));}

二、双指针法——js实现

    /** * @param {number[]} nums * @param {number} target * @return {number} */const threeSumClosest = function (nums, target) {  const len = nums.length  nums.sort((a, b) => { return a - b })  let best = Infinity  for (let i = 0; i < len; i++) {    // 去除首层循环反复的元素    if (i > 0 && nums[i] === nums[i - 1]) {      continue    }    let tail = len - 1    let head = i + 1    while (head < tail) {      // 求和      const sum = nums[i] + nums[head] + nums[tail]      // 更新三元素之和      if (Math.abs(sum - target) < Math.abs(best - target)) {        best = sum      }      if (sum > target) {        // 右指针左移1        tail--        // 左指针去重        while (nums[tail] === nums[tail + 1]) {          tail--        }      } else if (sum < target) {        // 左指针右移        head++        // 右指针去重        while (nums[head] === nums[head - 1]) {          head++        }      } else {        // sum与target相等时,间接返回target        return target      }    }  }  return best}console.log(threeSumClosest([-1, 2, 1, -4], 1))

  • 工夫复杂度:O(n^2),其中n是数组nums 的长度。咱们首先须要O(nlogn)的工夫对数组进行排序,随后在枚举的过程中,应用一重循环O(n)枚举a,双指针O(n)枚举b和c,故一共是O(n^2)。
  • 空间复杂度:O(logn)。排序须要应用O(logn)的空间。然而咱们批改了输出的数组nums,在理论状况下不肯定容许,因而最坏状况就是应用了一个额定的数组存储了nums的正本并进行排序,此时应用数组的空间复杂度为O(n)。排序空间复杂度为O(logn),额定的新数组空间复杂度是O(n),因而综合起来就是O(logn)。