【C++算法打怪专栏】LeetCode 1. 两数之和(哈希表解法总结)
一、 题目链接
- LeetCode 官方网址 :LeetCode 1. 两数之和
二、 核心思路与优化
- 暴力解法的局限 :如果用两层循环去遍历所有组合,时间复杂度会达到 O ( N 2 ) O(N^2) O(N2),数据量大时会超时。
- 哈希表优化(一趟哈希) :
- 边遍历数组,边将元素及其下标存入
unordered_map(键存数值,值存下标)。 - 在存入之前,先检查哈希表中是否存在
target - nums[i](即我们需要的另一个数)。 - 核心优势 :时间复杂度直接降至 O ( N ) O(N) O(N),且由于是"先查找后插入",完美避免了把"元素自身"重复利用的问题。
- 边遍历数组,边将元素及其下标存入
三、 C++ 标准精简源码
cpp
#include <vector>
#include <unordered_map>
using namespace std;
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int, int> mp; // 键:数值,值:对应下标
for (int i = 0; i < nums.size(); i++) {
int num2 = target - nums[i];
// 如果在哈希表中找到了另一半,直接返回各自的下标
if (mp.find(num2) != mp.end()) {
return {mp[num2], i};
}
// 没找到就把当前元素存入哈希表
mp[nums[i]] = i;
}
return {}; // 题目保证有解,防警告兜底
}
};
四、 复杂度分析
- 时间复杂度 : O ( N ) O(N) O(N),其中 N N N 是数组的长度。我们只对数组进行了一次单循环,哈希表的查找和插入平均时间复杂度均为 O ( 1 ) O(1) O(1)。
- 空间复杂度 : O ( N ) O(N) O(N),最坏情况下(如答案在最后两个数或无解前),需要把所有元素存入哈希表中。