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

两数之和问题详解:从暴力到哈希表的优化之路

引言

两数之和问题是算法学习中的经典入门题目,也是面试中高频出现的基础题型。作为LeetCode的第一道题目,它不仅考察了对数组操作的基本理解,更蕴含了从暴力解法到高效算法的优化思维。本文将详细解析这一问题的多种解法,重点介绍如何利用哈希表将时间复杂度从O(n²)降至O(n),并通过实例验证算法的正确性。

问题描述

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

约束条件

  • 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]
代码实现
python 复制代码
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),因为后出现的元素会查找先前存入的元素
代码实现
python 复制代码
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字典使用开放寻址法处理哈希冲突,保证查找效率
  • 键值选择:本题以元素值为键,索引为值,适合查找值对应的索引

结论

两数之和问题展示了数据结构对算法效率的巨大影响。通过哈希表的应用,我们成功将时间复杂度从O(n²)优化至O(n),体现了"空间换时间"的经典算法设计思想。在实际开发中,应根据问题约束选择合适的算法:

  • 小规模数据或空间受限场景:可考虑暴力法
  • 大规模数据或时间敏感场景:哈希表方法是更优选择

掌握这种优化思维,对于解决更复杂的算法问题具有重要意义。建议读者进一步研究哈希表的实现原理及其在其他问题中的应用,如子数组和问题、频率统计问题等。

完整代码

python 复制代码
def twoSum(nums, target):
    """
    两数之和:找出数组中和为目标值的两个整数的索引
    
    参数:
        nums: List[int] - 整数数组
        target: int - 目标和
        
    返回:
        List[int] - 两个整数的索引列表
    """
    num_map = {}  # 存储已遍历元素的值:索引
    for index, num in enumerate(nums):
        complement = target - num
        if complement in num_map:
            return [num_map[complement], index]
        num_map[num] = index
    return []  # 题目保证有解,实际不会执行到此

# 测试示例
if __name__ == "__main__":
    print(twoSum([2,7,11,15], 9))   # 输出: [0, 1]
    print(twoSum([3,2,4], 6))       # 输出: [1, 2]
    print(twoSum([3,3], 6))         # 输出: [0, 1]
相关推荐
Neil今天也要学习12 小时前
永磁同步电机无速度算法--基于相位超前校正的LESO
算法·1024程序员节
码农多耕地呗12 小时前
力扣226.翻转二叉树(java)
算法·leetcode·职场和发展
CodeCraft Studio13 小时前
国产化Excel开发组件Spire.XLS教程:在Python中将Pandas DataFrame导出到Excel的详细教程
python·excel·pandas
B站_计算机毕业设计之家14 小时前
python舆情分析可视化系统 情感分析 微博 爬虫 scrapy爬虫技术 朴素贝叶斯分类算法大数据 计算机✅
大数据·爬虫·python·scrapy·数据分析·1024程序员节·舆情分析
B站_计算机毕业设计之家14 小时前
基于python人脸识别系统 人脸检测 实时检测 深度学习 Dlib库 ResNet深度卷积神经网络 pyqt设计 大数据(源码)✅
python·深度学习·目标检测·计算机视觉·信息可视化·人脸识别·1024程序员节
汤姆yu14 小时前
2026版基于python大数据的电影分析可视化系统
大数据·python·1024程序员节·电影分析可视化
Pa2sw0rd丶14 小时前
Python 循环导入详解:为什么会导致生产环境崩溃及企业级解决方案
后端·python
IT古董14 小时前
【第五章:计算机视觉-项目实战之推荐/广告系统】2.粗排算法-(3)理解粗排模型之在线部分:在线架构及对双塔的应用
算法·1024程序员节
大数据张老师14 小时前
数据结构——平衡二叉树
数据结构·算法·查找
py有趣14 小时前
LeetCode算法学习之合并区间
学习·算法·leetcode