[力扣]给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出和为[leetcode 001]

1.两数之和 问题求解

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

题目1

约束条件

  • 2 ≤ nums.length ≤ 10⁴
  • -10⁹ ≤ nums[i] ≤ 10⁹
  • -10⁹ ≤ target ≤ 10⁹
  • 只会存在一个有效答案

示例

  • 示例1:输入:nums = [2,7,11,15], target = 9 → 输出:[0,1](解释:2+7=9)
  • 示例2:输入:nums = [3,2,4], target = 6 → 输出:[1,2](解释:2+4=6)
  • 示例3:输入:nums = [3,3], target = 6 → 输出:[0,1](解释:3+3=6)

解题思路

方法一:暴力枚举法(Brute Force)

思路解析

暴力枚举法是最直观的解决方案,通过双重循环遍历数组中的每一个元素,检查每对元素的和是否等于目标值。具体步骤如下:

  1. 外层循环遍历数组中的每个元素nums[i](索引i从0到n-1)
  2. 内层循环遍历当前元素之后的所有元素nums[j](索引j从i+1到n-1)
  3. nums[i] + nums[j] == target,则返回[i, j]
代码实现
def twoSum(nums, target):
    n = len(nums)
    for i in range(n):
        for j in range(i+1, n):
            if nums[i] + nums[j] == target:
                return [i, j]
    return []  # 题目保证有解,此句可省略
复杂度分析
  • 时间复杂度:O(n²),其中n为数组长度。双重循环导致最坏情况下需要检查n(n-1)/2对元素
  • 空间复杂度:O(1),只使用了常数级别的额外空间
局限性

虽然暴力法简单易懂,但在数组长度较大时(如接近10⁴),O(n²)的时间复杂度会导致运算时间显著增加,可能出现超时问题。因此需要更高效的算法。

方法二:哈希表优化法(Hash Table)

思路解析

哈希表(Hash Table)是解决查找问题的高效数据结构,其平均查找时间复杂度为O(1)。通过空间换时间的策略,我们可以将查找互补数的过程优化为常数时间:

  1. 创建一个空的哈希表(字典),用于存储已遍历元素的值和对应的索引
  2. 遍历数组中的每个元素nums[i],计算与目标值的差值complement = target - nums[i]
  3. 检查complement是否在哈希表中:
    • 若存在,则返回[哈希表[complement], i]
    • 若不存在,则将当前元素nums[i]及其索引i存入哈希表
  4. 继续遍历直到找到解
核心优势
  • 只需遍历一次数组,时间复杂度降至O(n)
  • 通过哈希表实现互补数的快速查找,避免了内层循环
  • 自然处理重复元素(如示例3),因为后出现的元素会查找先前存入的元素
代码实现
def twoSum(nums, target):
    # 创建哈希表存储已遍历元素的值和索引
    num_map = {}
    for i, num in enumerate(nums):
        # 计算互补数
        complement = target - num
        # 检查互补数是否已存在于哈希表中
        if complement in num_map:
            # 若存在,返回互补数的索引和当前索引
            return [num_map[complement], i]
        # 若不存在,将当前元素存入哈希表
        num_map[num] = i
    return []  # 题目保证有解,此句可省略
复杂度分析
  • 时间复杂度:O(n),其中n为数组长度。只需遍历一次数组,每次哈希表操作平均为O(1)
  • 空间复杂度:O(n),最坏情况下需要存储n-1个元素到哈希表中

示例详解

示例1:nums = [2,7,11,15], target = 9

  1. 遍历i=0,num=2:complement=9-2=7。哈希表为空,存入{2:0}
  2. 遍历i=1,num=7:complement=9-7=2。哈希表中存在2,返回[0,1]

示例2:nums = [3,2,4], target = 6

  1. 遍历i=0,num=3:complement=6-3=3。哈希表为空,存入{3:0}
  2. 遍历i=1,num=2:complement=6-2=4。哈希表中不存在4,存入{3:0, 2:1}
  3. 遍历i=2,num=4:complement=6-4=2。哈希表中存在2,返回[1,2]

示例3:nums = [3,3], target = 6

  1. 遍历i=0,num=3:complement=6-3=3。哈希表为空,存入{3:0}
  2. 遍历i=1,num=3:complement=6-3=3。哈希表中存在3,返回[0,1]

进阶思考

算法优化空间

  • 早期终止:哈希表方法已实现一次遍历完成查找,无法进一步降低时间复杂度
  • 空间优化:在空间受限场景下,可结合排序+双指针法(但会改变索引,需额外存储原始索引)

类似问题扩展

  • 三数之和:找出数组中所有和为0的三元组(需去重,复杂度O(n²))
  • 四数之和:类似三数之和,增加一层循环(复杂度O(n³))
  • 两数之和 II - 输入有序数组:可使用双指针法实现O(n)时间和O(1)空间

哈希表实现细节

  • 冲突处理:Python字典使用开放寻址法处理哈希冲突,保证查找效率
  • 键值选择:本题以元素值为键,索引为值,适合查找值对应的索引
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

韩进520

你的鼓励将是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值