LeetCode 1.「两数之和」的三种解法(JS 代码实现)

439 阅读3分钟

前言

“两数之和”是 LeetCode 上最经典的入门题之一。它不仅考察基础的编程能力,还能让我们体会到不同算法思路的优劣。本文将用最通俗的语言,带你用 JavaScript 实现三种常见解法,并详细分析每种方法的优缺点,让零基础的小白也能轻松看懂!


题目描述

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

示例:

输入: nums = [2, 7, 11, 15], target = 9
输出: [0, 1]
// 因为 nums[0] + nums[1] == 9

方法一:暴力解法(双重循环)

思路

最直接的办法就是:把数组里的每一对数字都加一遍,看看有没有等于目标值的。用两个 for 循环,外层选第一个数,内层选第二个数。

代码实现

var twoSum = function (nums, target) {
    for (var i = 0; i < nums.length; i++) {
        for (var j = i + 1; j < nums.length; j++) {
            if (nums[i] + nums[j] === target) {
                return [i, j];
            }
        }
    }
};

复杂度分析

  • 时间复杂度:O(n²),每个数都要和后面的数配对一次。
  • 空间复杂度:O(1),没有用到额外空间。

通俗解释

就像你在一堆钥匙里找一对能开门的钥匙,你把每一把钥匙都和其他钥匙试一遍,直到找到合适的那一对。虽然简单粗暴,但效率不高。


方法二:利用 indexOf 方法

思路

我们可以用数组自带的 indexOf 方法,查找目标值减去当前数字的另一个数是否存在于数组中。注意要排除自己和自己配对的情况。

代码实现

var twoSum = function (nums, target) {
    for (let i = 0; i < nums.length; i++) {
        let item = target - nums[i];
        let index = nums.indexOf(item);
        // 不能和自己配对
        if (index !== -1 && index !== i) {
            return [i, index];
        }
    }
};

复杂度分析

  • 时间复杂度:O(n²),因为 indexOf 本身也是 O(n)。
  • 空间复杂度:O(1)。

通俗解释

每次拿到一个钥匙,就在钥匙堆里找有没有能和它配对的钥匙(用 indexOf 查找),但不能找自己。


方法三:哈希表法(空间换时间)

思路

有没有更快的方法?有!我们可以用“空间换时间”的思路。用一个哈希表(对象)来记录已经遍历过的数字和它们的下标。每次遍历到一个新数字时,看看目标值减去这个数字的结果是不是已经在哈希表里了,如果在,说明找到了答案。

代码实现

var twoSum = function (nums, target) {
    let diffs = {};
    for (let i = 0; i < nums.length; i++) {
        let item = target - nums[i];
        if (diffs[item] !== undefined) {
            return [diffs[item], i];
        }
        diffs[nums[i]] = i;
    }
};

复杂度分析

  • 时间复杂度:O(n),只需要遍历一遍数组。
  • 空间复杂度:O(n),哈希表最多存下所有数字。

通俗解释

就像你在找钥匙配对时,顺手把每把钥匙的形状记在本子上。每拿到一把新钥匙,你就查查本子上有没有能和它配对的钥匙。如果有,立刻找到答案;如果没有,就把这把钥匙记下来,继续找下一把。


三种方法对比总结

方法时间复杂度空间复杂度适用场景
暴力枚举法O(n²)O(1)小数据量
indexOf法O(n²)O(1)小数据量
哈希表法O(n)O(n)需要高效查找
  • 想提升效率,哈希表法是最常用的面试解法。
  • indexOf 方法适合理解数组查找的原理,但效率和暴力法差不多。

结语

“两数之和”虽然是 LeetCode 的入门题,但它背后蕴含的算法思想却非常重要。通过这道题,你可以学会如何用不同的思路解决同一个问题,也能体会到“空间换时间”的精髓。希望这篇文章能帮你打下坚实的算法基础,开启刷题之路!