算法题:两数之和以及三数之和

152 阅读2分钟

一. 两数之和(Two Sum)

题目描述
给定一个整数数组 nums 和一个目标整数 target,请你在该数组中找出和为目标整数的那两个整数,并返回它们的数组下标。

示例

输入: nums = [2, 7, 11, 15], target = 9
输出: [0, 1]
解释:nums[0] + nums[1] = 2 + 7 = 9,所以返回 [0, 1]。

解题思路

  1. 我们可以使用一个哈希表(对象或映射)来存储数组中的元素及其下标。
  2. 对于每个元素 num,我们计算 complement = target - num,然后检查哈希表中是否存在这个 complement
  3. 如果存在,返回该元素的下标和当前元素的下标。
  4. 如果不存在,将当前元素和它的下标存入哈希表。

JavaScript 代码实现

function twoSum(nums, target) {
    const map = new Map(); // 创建一个哈希表
    for (let i =0; i < nums.length; i++) {
        const complement = target - nums[i]; // 计算当前元素的补数
        if (map.has(complement)) { // 检查补数是否在哈希表中
            return [map.get(complement), i]; // 如果存在,返回下标
        }
        map.set(nums[i], i); // 如果不存在,将当前元素和其下标存入哈希表
    }
    throw new Error("No two sum solution"); // 如果没有找到解,抛出错误
}

// 示例
console.log(twoSum([2, 7, 11, 15], 9)); // 输出: [0, 1]

二. 三数之和(Three Sum)

题目描述
给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c 使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。

示例

输入: nums = [-1, 0, 1, 2, -1, -4]
输出: [[-1, -1, 2], [-1, 0, 1]]

解题思路

  1. 首先,对数组进行排序。
    2 使用外层循环来固定一个元素 a,然后用双指针法来找到另外两个元素 bc
  2. 如果 a + b + c == 0,我们找到一个三元组,将其加入结果列表。
  3. 为了避免重复,我们要跳过相同的元素。
  4. 如果当前和小于0,则左指针右移,增大和;如果大于0,则右指针左移,减小和。

JavaScript 代码实现

function threeSum(nums) {
    const result = [];
    nums.sort((a, b) => a - b); // 排序
    for (let i = 0; i < nums.length - 2; i++) {
        if (i > 0 && nums[i] === nums[i - 1]) continue; // 跳过重复元素
        let left = i + 1; // 左指针
        let right = nums.length - 1; // 右指针
        while (left < right) {
            const sum = nums[i] + nums[left] + nums[right]; // 计算和
            if (sum === 0) {
                result.push([nums[i], nums[left], nums[right]]); // 找到三元组
                while (left < right && nums[left] === nums[left + 1]) left++; // 跳过重复元素
                while (left < right && nums[right] === nums[right - 1]) right--; // 跳过重复元素
                left++;
                right--;
            } else if (sum < 0) {
                left++; // 增大和
            } else {
                right--; // 减小和
            }
        }
    }
    return result; // 返回结果
}

// 示例console.log(threeSum([-1, 0, 1, 2, -1, -4])); // 输出: [[-1, -1, 2], [-1, 0, 1]]