(1)LeetCode 1. 两数之和

LeetCode 1. 两数之和

题目描述

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

你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。

你可以按任意顺序返回答案。

示例:

复制代码
输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1]。

解题思路

最直观的方法是使用两层循环暴力枚举,时间复杂度 O(n²)。为了优化,我们可以利用哈希表(unordered_map)将查找时间从 O(n) 降低到 O(1)。

核心思想:一边遍历数组,一边将已经遍历过的元素存入哈希表 。对于当前元素 nums[i],计算其需要的配对数 r = target - nums[i],然后检查哈希表中是否已经存在 r

  • 如果存在,说明之前出现过某个数恰好与当前数之和为 target,直接返回两个下标(之前那个数的下标和当前下标 i)。
  • 如果不存在,则将当前元素 nums[i] 及其下标 i 存入哈希表,继续遍历。

由于题目保证有唯一解,因此遍历过程中一定会找到答案。

代码实现(C++)

cpp 复制代码
class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        // 创建哈希表,key 为数组元素值,value 为该元素在数组中的下标
        unordered_map<int, int> heap;
        
        // 遍历数组
        for (int i = 0; i < nums.size(); i++) {
            int r = target - nums[i];           // 计算当前元素需要的另一个数
            
            // 如果需要的数已经在哈希表中,说明找到了答案
            if (heap.count(r)) {
                return {heap[r], i};            // 返回之前的下标和当前下标
            }
            
            // 否则将当前元素存入哈希表,供后续元素查找
            heap[nums[i]] = i;
        }
        
        // 根据题意,不会执行到这里,但函数需要返回值,故返回空数组
        return {};
    }
};

复杂度分析

  • 时间复杂度:O(n),其中 n 是数组的长度。我们只遍历了一次数组,每次哈希表的查找和插入操作都是 O(1)。
  • 空间复杂度:O(n),哈希表最多需要存储 n 个元素。

注意事项

  1. 哈希表为什么用 unordered_map
    unordered_map 基于哈希表实现,平均情况下插入和查找的时间复杂度为 O(1),而 map 基于红黑树实现,是 O(log n),因此本题选用 unordered_map 更高效。

  2. 为什么先检查再插入?

    如果将当前元素先插入哈希表再检查,那么对于 nums = [3,3]target = 6 的情况,遍历第一个3时插入哈希表,第二个3查找时会在哈希表中找到自己(即同一个元素用了两次),导致错误。因此必须先检查再插入,确保不会重复使用同一元素。

  3. 返回值 {heap[r], i} 的顺序任意,题目允许任意顺序返回两个下标。

  4. 题目保证有解 ,因此不需要考虑找不到答案的情况,但为了函数完整性,代码最后保留了 return {}

总结

本题是哈希表的经典应用,通过空间换时间,将两数之和问题优化到线性时间复杂度。掌握这种"边遍历边记录"的思路,可以解决很多类似的问题,例如"三数之和"、"四数之和"的部分优化。

相关推荐
一叶落4382 小时前
LeetCode 6. Z 字形变换(C语言详解)
c语言·数据结构·算法·leetcode
米粒13 小时前
力扣算法刷题 Day 15
算法·leetcode·职场和发展
Frostnova丶4 小时前
(10)LeetCode 560. 和为K的子数组
算法·leetcode·哈希算法
j_xxx404_5 小时前
LeetCode模拟算法精解II:外观数列与数青蛙
数据结构·c++·算法·leetcode
Tisfy6 小时前
LeetCode 3070.元素和小于等于 k 的子矩阵的数目:原地修改(前缀和思想)
算法·leetcode·前缀和·矩阵
喵喵蒻葉睦6 小时前
力扣 hot100 最小覆盖子串 哈希表 滑动窗口 Java 题解
java·算法·leetcode·哈希算法·散列表·滑动窗口
一叶落4387 小时前
【LeetCode 12】整数转罗马数字(C语言)| 贪心算法详解
c语言·数据结构·c++·算法·leetcode·贪心算法
一叶落4387 小时前
【LeetCode 289】生命游戏(C语言)|原地算法 + 状态标记法
c语言·数据结构·算法·leetcode·游戏
j_xxx404_7 小时前
LeetCode模拟算法精解I:替换问号,提莫攻击与Z字形变换
开发语言·数据结构·c++·算法·leetcode
一叶落43817 小时前
题目:15. 三数之和
c语言·数据结构·算法·leetcode