返回

LeetCode 15. 三数之和:深度剖析 JavaScript 双循环 + 哈希表解法

前端

概述

LeetCode 15. 三数之和 是一道经典的数组和问题,要求您在给定数组中找到三个元素的组合,使得它们的和等于给定目标值。

例如,给定数组 nums = [-1, 0, 1, 2, -1, -4] 和目标值 target = 0,其三数之和解集为:

[-1, -1, 2]
[-1, 0, 1]

为了解决这个问题,我们将使用 JavaScript 中的双循环和哈希表来实现。

解题思路

我们的解题思路是首先对数组进行排序,然后使用双循环来生成所有可能的数字组合。对于每个组合,我们使用哈希表来检查是否包含第三个数字,使得它们的和等于给定目标值。

如果找到这样的组合,我们将将其添加到结果集中。

代码实现

/**
 * LeetCode 15. 三数之和
 *
 * 给定一个包含 n 个整数的数组 nums 和一个目标值 target,找出 nums 中三个整数的组合,使得它们的和等于 target。
 *
 * 示例:
 *
 * 输入: nums = [-1, 0, 1, 2, -1, -4], target = 0
 * 输出: [[-1, -1, 2], [-1, 0, 1]]
 *
 * @param {number[]} nums
 * @param {number} target
 * @return {number[][]}
 */
const threeSum = (nums, target) => {
  // 对数组进行排序
  nums.sort((a, b) => a - b);

  // 结果集
  const result = [];

  // 双循环
  for (let i = 0; i < nums.length - 2; i++) {
    // 排除大于 0 的数字
    if (nums[i] > 0) {
      break;
    }

    // 如果当前数字与前一个数字相同,则跳过
    if (i > 0 && nums[i] === nums[i - 1]) {
      continue;
    }

    // 设置左右指针
    let left = i + 1;
    let right = nums.length - 1;

    // 哈希表
    const set = new Set();

    // 遍历数组
    while (left < right) {
      // 计算当前数字之和
      const sum = nums[i] + nums[left] + nums[right];

      // 如果等于目标值,则将其添加到结果集中
      if (sum === target) {
        result.push([nums[i], nums[left], nums[right]]);

        // 将当前数字添加到哈希表中
        set.add(nums[left]);

        // 移动左指针和右指针
        left++;
        right--;

        // 如果当前数字与前一个数字相同,则跳过
        while (left < right && nums[left] === nums[left - 1]) {
          left++;
        }

        // 如果当前数字与前一个数字相同,则跳过
        while (left < right && nums[right] === nums[right + 1]) {
          right--;
        }
      }
      // 如果小于目标值,则移动左指针
      else if (sum < target) {
        left++;
      }
      // 如果大于目标值,则移动右指针
      else {
        right--;
      }
    }
  }

  // 返回结果集
  return result;
};

时间复杂度分析

双循环的时间复杂度为 O(n^2),哈希表查找的时间复杂度为 O(1),因此总的时间复杂度为 O(n^2)。

空间复杂度分析

哈希表的空间复杂度为 O(n),因此总的空间复杂度为 O(n)。

结语

在这篇文章中,我们详细探讨了 LeetCode 15. 三数之和 这道题的解题思路和详细实现。我们使用 JavaScript 中的双循环和哈希表来解决这个问题,并提供了详细的注释和示例代码,帮助您轻松理解并掌握这种解法。

如果您有任何疑问或建议,欢迎在评论区留言。