返回

两数之和 II - 输入有序数组:JavaScript 双指针妙解,效率加倍!

前端

踏破LeetCode 167:JavaScript双指针解法,解锁两数之和新境界

前言

在LeetCode 167题中,我们面临着一个经典的「两数之和」问题,不同之处在于,这次给定的是一个已经排序的有序数组,如何利用这个条件来优化我们的解法,让我们用JavaScript来实现一个高效的双指针算法,轻松搞定「两数之和 II」!

算法原理

双指针算法是一种常见的算法设计范式,它利用了数据结构的特定性质来提高算法效率。对于「两数之和 II」问题,我们可以将数组视为一个连续的数轴,使用两个指针分别指向数组的首尾元素,比较它们的和与目标值的大小,并根据比较结果移动指针的位置。具体来说,算法步骤如下:

  1. 初始化两个指针:left指向数组第一个元素,right指向数组最后一个元素。
  2. 计算两个指针指向的元素之和sum
  3. 判断sum与目标值target的关系:
    • sum < target,则移动left指针向右,以增加和的值。
    • sum > target,则移动right指针向左,以减小和的值。
    • sum = target,则找到一组解,将指针位置记录下来,继续寻找其他解。

JavaScript代码实现

/**
 * 给定一个包含 n 个整数的升序数组 nums 和一个目标值 target,返回满足两数之和等于 target 的所有下标对。
 * 你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案中只能使用一次。
 *
 * @param {number[]} nums 排序数组
 * @param {number} target 目标值
 * @return {number[][]} 所有满足条件的下标对
 */
const twoSum = (nums, target) => {
  const result = [];
  let left = 0;
  let right = nums.length - 1;

  while (left < right) {
    const sum = nums[left] + nums[right];
    if (sum === target) {
      result.push([left, right]);
      // 跳过重复的元素
      while (left < right && nums[left] === nums[left + 1]) {
        left++;
      }
      while (left < right && nums[right] === nums[right - 1]) {
        right--;
      }
      // 移动指针
      left++;
      right--;
    } else if (sum < target) {
      left++;
    } else {
      right--;
    }
  }

  return result;
};

算法分析

  • 时间复杂度:由于双指针算法在最坏情况下需要遍历整个数组一次,因此时间复杂度为O(n),其中n是数组的长度。
  • 空间复杂度:该算法只需要常数个变量来存储指针和中间结果,因此空间复杂度为O(1)。

结语

通过本文,我们不仅学习了双指针算法的原理,还掌握了如何使用JavaScript实现「两数之和 II」问题的解法。这种算法以其简洁、高效的特点,在解决此类问题时具有很强的实用性。作为一名程序员,掌握双指针算法不仅可以帮助你轻松解决LeetCode中的难题,还能为你日后的编程生涯增添一笔宝贵的财富。