返回

用JavaScript在 LeetCode 上征服“两数之和 II - 输入有序数组”:分而治之大显神通!

前端

前言

“两数之和 II - 输入有序数组”是 LeetCode 上一个经典问题,要求你找到一个有序数组中两数之和等于指定目标值的索引。与普通“两数之和”问题不同的是,此题要求数组已按升序排列,这为我们解决问题提供了独特的机会。

分而治之算法

分而治之是一种将大问题分解成较小、更易管理的部分,然后逐个解决这些部分并合并其结果的算法。在解决“两数之和 II”问题时,我们可以使用分而治之算法按如下步骤操作:

  1. 基线情况: 如果数组长度为 0 或 1,则不存在满足要求的索引对。返回 -1。
  2. 分治: 将数组分成两部分。使用二分法查找目标值在右半部分中的位置。
  3. 合并: 如果目标值在右半部分中,则使用双指针从左半部分查找目标值的补数。否则,使用双指针从右半部分查找目标值的补数。
  4. 返回: 返回找到的索引对,或 -1。

JavaScript 代码示例

function twoSum(numbers, target) {
  // 检查基线情况
  if (numbers.length < 2) {
    return -1;
  }

  // 分治
  const mid = Math.floor(numbers.length / 2);
  const rightIndex = binarySearch(numbers, mid, numbers.length - 1, target);

  // 合并
  if (rightIndex !== -1) {
    const leftIndex = findComplement(numbers, 0, mid - 1, target - numbers[rightIndex]);
    if (leftIndex !== -1) {
      return [leftIndex, rightIndex];
    }
  } else {
    const leftIndex = findComplement(numbers, mid, numbers.length - 1, target - numbers[rightIndex]);
    if (leftIndex !== -1) {
      return [leftIndex, rightIndex];
    }
  }

  // 未找到满足要求的索引对
  return -1;
}

// 在有序数组中使用二分法查找目标值
function binarySearch(numbers, left, right, target) {
  while (left <= right) {
    const mid = Math.floor((left + right) / 2);
    if (numbers[mid] === target) {
      return mid;
    } else if (numbers[mid] < target) {
      left = mid + 1;
    } else {
      right = mid - 1;
    }
  }
  return -1;
}

// 使用双指针查找目标值的补数
function findComplement(numbers, left, right, target) {
  while (left <= right) {
    const mid = Math.floor((left + right) / 2);
    if (numbers[mid] === target) {
      return mid;
    } else if (numbers[mid] < target) {
      left = mid + 1;
    } else {
      right = mid - 1;
    }
  }
  return -1;
}

总结

使用分而治之算法可以有效解决“两数之和 II - 输入有序数组”问题。通过将数组分成较小部分并逐个解决,我们可以高效地找到满足要求的索引对。本文中的 JavaScript 代码示例提供了分而治之算法的详细实现,供你学习和实践。

通过掌握分而治之等强大算法,你可以提升解决复杂编程问题的技能,并为在 LeetCode 等编程竞赛平台上取得成功做好准备。