题干描述

给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出两个不同的元素,使得它们的和等于 target,并返回这两个元素的数组索引。你可以按任意顺序返回答案,且每个输入保证存在唯一解。

要求​:

  1. 不能重复使用同一元素两次(即两个元素的索引必须不同)。
  2. 若存在多个解,只需返回任意一个正确解即可(但题干保证唯一解)。

示例 1
输入:nums = [3, 2, 4], target = 6
输出:[1, 2]
解释:nums[1] + nums[2] = 2 + 4 = 6,索引为 [1, 2]

示例 2
输入:nums = [5, -1, 12, 7], target = 11
输出:[1, 3]
解释:nums[1] + nums[3] = (-1) + 7 = 6;但无其他解,唯一正确答案为 [-1, 7],对应索引 [1, 3]


提示​:
System Message

  • 2 <= nums.length <= 10^4
  • -10^9 <= nums[i] <= 10^9
  • -10^9 <= target <= 10^9
  • 数组中存在且仅存在一个有效答案

如何解决?

使用一趟哈希表遍历(时间复杂度 ​O(n)​),在遍历时检查当前元素的补数(即 target - nums[i])是否已存在哈希表中。如果存在,直接返回结果;否则记录当前元素及其索引。

解题思路

  1. 哈希表存储​:创建一个哈希表(在JavaScript中可以使用Map或对象),用于存储数组元素的值及其对应的索引。
  2. 遍历数组​:遍历数组中的每个元素,对于每个元素,计算其补数(即目标值减去当前元素的值)。
  3. 查找补数​:检查哈希表中是否存在该补数:
    • 如果存在,则返回当前元素的索引和补数对应的索引。
    • 如果不存在,则将当前元素的值及其索引存入哈希表。
  4. 返回结果​:由于题目保证有唯一解,遍历结束后一定能找到结果。

代码实现

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);
    }
    return [];
}

代码解释

  • 哈希表初始化​:使用Map来存储已遍历的元素及其索引。
  • 遍历过程​:对于每个元素nums[i],计算其补数complement
  • 补数查找​:检查哈希表中是否存在补数,存在则直接返回结果。
  • 存储元素​:若补数不存在,则将当前元素存入哈希表,以便后续查找。