力扣hot100之1:两数之和
力扣hot100之1:两数之和

LeetCode 1:两数之和(Two Sum)题解

Two Sum 是一道非常经典的入门算法题。

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


题目示例

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

因为 nums[0] + nums[1] = 2 + 7 = 9,所以返回 [0,1]


一、暴力枚举

最直接的想法就是枚举所有可能的两个数,判断它们的和是否等于 target

代码

class Solution {

    public int[] twoSum(int[] nums, int target) {
        for (int i = 0; i < nums.length; i++) {
            for (int j = i + 1; j < nums.length; j++) {
                if (nums[i] + nums[j] == target) {
                    return new int[]{i, j};
                }
            }
        }
        throw new IllegalArgumentException("没有找到");
    }
}

思路分析

  • 外层循环固定第一个数 nums[i]

  • 内层循环寻找第二个数 nums[j]

  • 如果 nums[i] + nums[j] == target,直接返回两个下标

复杂度分析

  • 时间复杂度:O(n^2)

  • 空间复杂度:O(1)

这种写法思路清晰,但效率较低。当数组很大时,会做很多重复比较。


二、HashMap 优化

优化的核心思想是:

当遍历到当前元素 nums[i] 时,先判断 target - nums[i] 是否已经在前面出现过。

如果出现过,说明已经找到了答案。

因此,我们可以使用 HashMap 来记录已经遍历过的元素。

正确的 HashMap 记录方式

这里需要注意:

  • key:数组元素的值

  • value:该元素对应的下标

也就是说:

map.put(nums[i], i);

而不是“索引作为 key,元素作为 value”。


优化代码

import java.util.HashMap;
import java.util.Map;

class Solution {

    public int[] twoSum(int[] nums, int target) {
        Map<Integer, Integer> map = new HashMap<>();

        for (int i = 0; i < nums.length; i++) {
            int x = target - nums[i];

            if (map.containsKey(x)) {
                return new int[]{map.get(x), i};
            }

            // 把当前值和下标存入 map
            map.put(nums[i], i);
        }

        throw new IllegalArgumentException("没找到");
    }
}

思路拆解

假设:

nums = [2,7,11,15], target = 9

遍历过程如下:

第 1 轮

  • 当前元素:2

  • 需要寻找的值:9 - 2 = 7

  • map 中没有 7

  • 存入 map{2:0}

第 2 轮

  • 当前元素:7

  • 需要寻找的值:9 - 7 = 2

  • map 中存在 2

  • 返回结果:[0,1]

这样只需要遍历一遍数组,就能找到答案。


为什么这样做更快?

暴力解法需要两层循环,本质上是在不断尝试所有配对。

而使用 HashMap 后,我们可以把“查找另一个数是否存在”这件事优化到接近常数时间。

因此整体效率从:

  • 暴力枚举:O(n^2)

优化为:

  • 哈希表:O(n)


复杂度分析

时间复杂度

  • O(n)

数组只遍历一次,每次 HashMap 查询和插入的平均时间复杂度都是 O(1)

空间复杂度

  • O(n)

最坏情况下,数组中的所有元素都会被存进 HashMap

所以空间复杂度不是 Max{nums[i]},而是和存入哈希表的元素个数有关,即 O(n)


总结

这道题体现了一个非常重要的算法思想:

用空间换时间。

  • 暴力解法:实现简单,但效率低

  • HashMap 优化:多使用了额外空间,但把时间复杂度降到了 O(n)

对于 Two Sum 这类“边遍历边查找”的问题,哈希表通常都是非常自然的优化方式。


适合直接发布的结尾

如果你刚开始刷算法,这道题非常值得反复体会:

  1. 先写出暴力解法,保证正确性

  2. 再思考哪些重复操作可以优化

  3. 最后引入合适的数据结构(如 HashMap

很多中等题、甚至更难的题,本质上都是这种思考方式的延伸。

如果对您有帮助的话,能否支持一下博主?
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇