在LeetCode做简单数组题的第2天

学习错题复盘日志,面向初学者,记录自己踩坑、思考、顿悟的全过程,不是单纯题解。


前言

本人专业属于计算机大类,但基本不能主动回忆专业知识,目前在LeetCode做简单数组题。今天做到第1题两数之和,用到的哈希表相关知识,也是数据结构课学完很久几乎忘干净。
本文记录我的思考过程、bug、和对哈希表的理解,当作错题存档,方便以后回来复习。

题目:LeetCode 1.两数之和

描述:
给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那两个整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案,并且你不能使用两次相同的元素。可以按任意顺序返回答案。

测试示例1:
输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:nums[0] + nums[1] = 9

测试示例2:
输入:nums = [3,2,4], target = 6
输出:[1,2]

测试示例3:
输入:nums = [3,3], target = 6
输出:[0,1]

一、蘑菇的简单思路

循环遍历数组里每一个元素nums[i],用 target - nums[i] 得到需要配对的另一半divide。
判断divide是否存在数组中,如果存在,还要保证这个另一半不能是当前这个元素本身;找到两个下标,返回结果。

一开始写代码就出现语法错误:

# 错误代码
for i in range(nums):  # ❌错误:range里面必须传数字,应该是range(len(nums))

基础语法知识:range() 是 Python 中的一个内置函数,用于生成一个整数序列,常用于循环操作。它支持三个参数:start(起始值)、stop(结束值,不包含)和 step(步长)。

此外,找列表的元素下标虽然可用nums.index()可以实现,但是index()只会返回第一个匹配元素下标,且找不到会报错,只能用来理解思路,不适合正式提交。

二、蘑菇的解法:双层暴力循环

代码

class Solution:
    def twoSum(self, nums: list[int], target: int) -> list[int]:
        n = len(nums)
        for i in range(n):
            for j in range(i + 1, n):  # j从i后面开始,避免重复使用同一个元素
                if nums[i] + nums[j] == target:
                    return [i, j]

思路解释

固定外层下标i,内层j从i的下一个位置开始,两两组合尝试相加,一旦相加等于target,直接返回两个下标。

复杂度

  • 时间复杂度:O(n^2),两层循环
  • 空间复杂度:O(1),只使用了i,j两个临时变量,没有额外开辟大空间

缺点:数组很长的时候效率差。

三、最优解法:哈希表(字典)

完整代码

class Solution:
    def twoSum(self, nums: list[int], target: int) -> list[int]:
        hashmap = {}  # 初始化空字典!key存数组的值,value存对应的下标
        for i, num in enumerate(nums):
            divide = target - num
            # 第一步:先查表,看我们需要的另一半是否已经记录在字典里
            if divide in hashmap:
                return [hashmap[divide], i]
            # 第二步:查不到,才把当前数字和下标存入字典
            hashmap[num] = i

enumerate() 是 Python 的内置函数,用于在遍历可迭代对象时同时获取元素的索引和值。它返回一个可迭代对象,常用于需要索引和值的场景。

✅我当时的疑惑解答

  1. hashmap = {},一开始就是空字典,不是自带数据。字典是遍历过程中一点点写入的,像一个记事本。
  2. 顺序绝对不能颠倒:先查找,后存入!
    如果先存入当前数字再查找,会找到元素自己,返回同一个下标,违反题目“不能使用两次相同元素”的要求。
  3. 字典查找divide in hashmap平均是O(1),数组查找divide in nums是O(n)。

    通俗理解:字典就像通讯录,输入名字直接找到人;数组查找需要从头挨个翻。

手动模拟样例

nums=[3,3], target=6

  • 初始 hashmap = {}
  1. i=0,num=3
    divide = 6 - 3 = 3
    判断:3不在空字典{} → 存入 hashmap[3]=0,hashmap={3:0}.
  2. i=1,num=3
    divide = 6 - 3 = 3
    判断:3 在hashmap里面,hashmap[3]=0
    返回 [0,1] ✅

再模拟 nums=[3,2,4], target=6

  • 初始 hashmap={}
  1. i=0 num=3,divide=3,不在字典 → 存入
  2. i=1 num=2,divide=4,不在字典 → 存入
  3. i=2 num=4,divide=2,2存在,hashmap[2]=1 → 返回[1,2] ✅

复杂度

  • 时间复杂度:O(n),只遍历数组一遍,哈希查找近似常数时间。
  • 空间复杂度:O(n),需要开辟字典存储遍历过的数据。

核心思想:用空间换取更快的速度。

四、两种方法对比总结

方法 时间复杂度 空间复杂度 特点
双层暴力循环 O(n^2) O(1) 逻辑简单,大数据慢
哈希字典 O(n) O(n) 速度快,需要额外内存

五、总结

  1. 基础语法坑:range()里面只能放整数,遍历下标要用range(len(nums))。
  2. 哈希表核心:创建字典,边遍历边记录,先查,后存,字典初始是空。
  3. 时间复杂度:一层循环O(n),双层嵌套O(n^2)。
  4. 刷题方式:继续采用这种错题复盘模式,把思考过程、bug写下来,方便可以回顾。

学习计划回顾:现阶段巩固 Python 基础,只做LeetCode 简单题,重点训练独立写代码,不会深入复杂的部分。

六、本题自测

nums = [5, 1, 9], target =10,手动推演哈希解法,写出返回结果。

posted @ 2026-10-21 11:36  绝望蘑菇头  阅读(2)  评论(0)    收藏  举报