📊用 ES6 Map 一次遍历搞定 LeetCode 1. Two Sum | 超简洁模板题详解

86 阅读3分钟

关键词:LeetCode、Two Sum、ES6、Map、哈希表、一次遍历、JavaScript
适合读者:刚刷题的新手、前端er、对 ES6 语法感兴趣的同学
阅读时间:≈ 5 分钟


一、写在前面

Two Sum 作为 LeetCode 开篇第一题,常年位居「最多提交」排行榜榜首。
它看似人畜无害,实则暗藏玄机:

  • 暴力两重循环人人都能写,但时间复杂度 O(n²) 常常 TLE;
  • 用哈希表可以做到 O(n),但「对象 or Map」?「一次遍历 or 两次遍历」?
    今天咱们就用最地道的 ES6 Map 语法,把这道题写成“六行核心代码”的模板,让你面试时 30 秒手写无压力。

二、题目回顾

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

  • 每种输入只会对应一个答案;
  • 不能重复使用同一个元素;
  • 数组无序,长度 2 ≤ n ≤ 10⁴,元素范围 −10⁹ ≤ nums[i] ≤ 10⁹。

三、核心思路:一边遍历,一边“查户口”

  1. 我们需要快速判断:“target − 当前值”有没有出现过?
  2. 如果出现过,直接返回两个下标;
  3. 如果没出现过,把当前值“存档”,继续往后扫。
  4. 存档+查询都要求 O(1) → 哈希表是不二之选。

ES6 提供的 Map 正好满足:

  • 键可以是任意类型(负数、0、大整数都没问题);
  • 读写性能稳定;
  • API 语义清晰(has/get/set)。

四、代码实现(一次遍历版)

/**
 * @param {number[]} nums
 * @param {number} target
 * @return {number[]}
 */
const twoSum = (nums, target) => {
  const map = new Map();               // 数值 → 下标
  for (let i = 0; i < nums.length; i++) {
    const need = target - nums[i];     // 计算“补数”
    if (map.has(need)) {               // 补数已存在
      return [map.get(need), i];       // 直接返回答案
    }
    map.set(nums[i], i);               // 存档当前值
  }
  return [];                           // 题目保证有解,不会走到这里
};

提交截图
执行用时:60 ms 左右(LeetCode JS 引擎)
内存消耗:42 MB 左右
击败 98%+ 用户,妥妥的“模板级”表现。


五、复杂度分析

维度说明
时间复杂度O(n)每个元素最多被扫描一次,Map 操作 O(1)
空间复杂度O(n)最坏需要存 n−1 个元素

六、常见疑问 Q&A

  1. 问:用普通对象 {} 行不行?
    答:行,但 Map 更干净。

    • 对象原型链有默认属性,可能触发 hasOwnProperty 判断;
    • Map 的 key 可以是任意类型,负数、0、字符串统一处理;
    • Map 的迭代顺序与插入顺序一致,可读性更好。
  2. 问:两次遍历是不是更容易想?
    答:第一次遍历建表,第二次遍历查表,代码量翻倍,常数更大。
    一次遍历把“建”和“查”合并,思路更优雅。

  3. 问:如果题目要求返回数值而不是下标?
    答:把 map.set(nums[i], i) 改成 map.set(nums[i], nums[i]) 即可,但本题明确要下标。

  4. 问:Map 会被极端数据卡成 O(n) 查询吗?
    答:V8 底层对 Map 做了哈希+链表/红黑树优化,均摊 O(1),放心用。


七、延伸:模板化思维

Two Sum 的“查补数”思想,在很多变体里都能复用:

变体一句话思路
三数之和先排序,固定一个数,剩下转 Two Sum(双指针)
四数之和排序后,两层循环固定两个数,剩下转 Two Sum
两数之和(有序数组)双指针夹逼,O(n) 不用额外空间
两数之和(数据流)用 Set/Map 维护已看到元素,支持在线查询

把“哈希表+补数”装进口袋,后续刷题事半功倍。


八、结语

ES6 的 Map 不仅语法甜,还能让算法题秒变“一行查询、一行插入”的模板。
下次面试遇到 Two Sum,别忘了甩出这段 6 行核心代码,然后自信地跟面试官说:
“我只需要一次遍历。”

祝各位刷题愉快,offer 多多!
如果对你有帮助,点个赞或在评论区打卡吧~


原创文章 转载请注明出处,谢谢!