LeetCode 第一题

LeetCode 第一题(两数之和)用哈希表解法的核心是以空间换时间,将查找目标值的时间从 O (n) 降到 O (1),整体时间复杂度 O (n),空间复杂度 O (n)。

核心思路

遍历数组时,用哈希表(对象 / Map) 存储已遍历元素的值:对应索引 ;对当前元素nums[i],计算目标差值target - nums[i],若差值存在于哈希表中,直接返回[哈希表差值的索引, i];若不存在,将当前元素和索引存入哈希表,继续遍历。

可直接运行的 JS 代码(Map 版,推荐)

复制代码
/**
 * @param {number[]} nums
 * @param {number} target
 * @return {number[]}
 */
var twoSum = function(nums, target) {
    const map = new Map(); // 哈希表:key=数值,value=索引
    for (let i = 0; i < nums.length; i++) {
        const diff = target - nums[i];
        if (map.has(diff)) { // 差值已存在,找到解
            return [map.get(diff), i];
        }
        map.set(nums[i], i); // 未找到,存入当前元素
    }
    return []; // 题目保证有解,此句可省略
};

简化版(对象版)

复制代码
var twoSum = function(nums, target) {
    const obj = {};
    for (let i = 0; i < nums.length; i++) {
        const diff = target - nums[i];
        if (diff in obj) {
            return [obj[diff], i];
        }
        obj[nums[i]] = i;
    }
};

关键细节

  1. 为什么不用先存全部元素 :边遍历边存,避免同一元素被重复使用(如target=6,nums=[3,3],先查再存可正确匹配两个 3);
  2. Map vs 普通对象:Map 支持任意类型键,且不会与对象原型属性冲突,处理负数 / 0 更安全,推荐使用;
  3. 题目特性 :题目明确有且仅有一个解,无需处理多解 / 无解情况,遍历到解可直接返回。

对比暴力解法

解法 时间复杂度 空间复杂度 核心逻辑
暴力双重 for O(n²) O(1) 遍历所有元素两两组合
哈希表法 O(n) O(n) 哈希表快速查找目标差值

两数之和(哈希解法)核心边界测试用例

覆盖重复元素、负数、目标值为 0、单元素相邻匹配四大高频边界,附测试结果 + 代码适配性说明(上述 Map / 对象解法均完美适配)

1. 重复元素(核心易错题)
  • 用例:nums = [3,3], target = 6
  • 结果:[0,1]
  • 关键:边查边存 ,先判断diff=3是否在哈希表(初始空),再存入第一个 3,遍历第二个 3 时可匹配到第一个 3 的索引,避免同一元素重复使用。
2. 包含负数
  • 用例:nums = [2,7,-1,15], target = 6
  • 结果:[2,3]
  • 关键:Map / 对象对负数键无处理问题,比数组下标法更适配负数场景。
3. 目标值为 0
  • 用例:nums = [-1,0,1,2], target = 0
  • 结果:[0,2]
  • 关键:哈希表可正常存储 / 查找0和负数值,无特殊处理逻辑。
4. 相邻元素匹配(基础边界)
  • 用例:nums = [2,7,11,15], target = 9
  • 结果:[0,1]
  • 关键:遍历第二个元素 7 时,diff=2已在哈希表中,直接返回结果,是最基础的正常场景。
5. 元素为 0 的重复匹配
  • 用例:nums = [0,4,0,3], target = 0
  • 结果:[0,2]
  • 关键:哈希表按首次出现存储索引,后续匹配可精准拿到前置索引。

测试代码(可直接运行)

将上述用例代入解法,快速验证结果:

复制代码
var twoSum = function(nums, target) {
    const map = new Map();
    for (let i = 0; i < nums.length; i++) {
        const diff = target - nums[i];
        if (map.has(diff)) return [map.get(diff), i];
        map.set(nums[i], i);
    }
    return [];
};

// 测试用例执行
console.log(twoSum([3,3],6)); // [0,1]
console.log(twoSum([2,7,-1,15],6)); // [2,3]
console.log(twoSum([-1,0,1,2],0)); // [0,2]
console.log(twoSum([2,7,11,15],9)); // [0,1]
console.log(twoSum([0,4,0,3],0)); // [0,2]

边界坑点总结

  1. 先存后查 ,会导致重复元素用例失败(如[3,3]会匹配到同一索引);

  2. 用普通对象时,若数值为__proto__(极端情况)会冲突,Map 可彻底避免,推荐优先使用;

  3. 无需处理数组长度 < 2 的情况,题目明确有且仅有一个解,输入均为有效用例。

    const map = new Map();

    map.set('a', 5);
    map.set('b', 7);
    map.set('c', 9);

    console.log(map.get('a')); // 5
    console.log(map.has('b')); // true

相关推荐
阿珊和她的猫14 小时前
Chrome 的 SameSite 属性:原理与解决方案
前端·chrome
belldeep14 小时前
nodejs: 能在线编辑 Markdown 文档的 Web 服务程序,更多扩展功能
前端·node.js·markdown·mermaid·highlight·katax
程序员林北北14 小时前
【前端进阶之旅】一种新的数据格式:TOON
前端·javascript·vue.js·react.js·typescript·json
木斯佳14 小时前
前端八股文面经大全:2026-01-23快手AI应用方向前端实习一面面经深度解析
前端·人工智能·状态模式
容沁风15 小时前
react路由Cannot GET错误
前端·react.js·前端框架·sharp7
少云清15 小时前
【UI自动化测试】6_web自动化测试 _浏览器操作
前端·web自动化测试
globaldomain15 小时前
立海世纪:.com和.net域名哪个更适合你的网站
大数据·前端·人工智能·新媒体运营·国外域名·域名注册
phltxy15 小时前
Vue Router:从入门到实战
前端·javascript·vue.js
Zhencode16 小时前
Vue3核心运行时之runtime-core
前端·javascript·vue.js
木斯佳16 小时前
前端八股文面经大全:腾讯WXG技术架构前端面试(2025-11-19)·面经深度解析
前端·面试·架构