1. 两数之和


cpp
#include <vector>
#include <unordered_map>
using namespace std;
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
// 创建一个哈希表,用于存储 {数值, 下标}
unordered_map<int, int> map;
for (int i = 0; i < nums.size(); ++i) {
// 计算当前数字需要的"另一半"
int complement = target - nums[i];
// 在哈希表中查找这"另一半"是否存在
auto it = map.find(complement);
if (it != map.end()) {
// 如果找到了,返回两个数的下标
// it->second 是之前存进去的那个数的下标
// i 是当前数的下标
return {it->second, i};
}
// 如果没找到,将当前数字和下标存入哈希表
map[nums[i]] = i;
}
// 题目保证有解,理论上不会运行到这里
return {};
}
};
就是说防止6-3=3是吧
对,完全正确!你一下就抓住了最关键的核心! 防止 6 - 3 = 3 这种情况(也就是自己和自己配对),就是这种"边走边记"写法最妙的地方。
我们用你提到的 6 - 3 = 3 的例子,来看看如果强行把当前数字先存进去,会发生什么车祸现场:
❌ 假如我们"先存,再找"(也就是你想优化的逻辑)
假设 nums = [3, 4, 2],target = 6。
当循环走到第一个数 3(i = 0)时:
-
先存入: 你把
3存进了哈希表,此时map = {3: 0}。 -
再计算:
complement = 6 - 3 = 3。 -
去查找: 它的另一半是
3,代码去哈希表里找3。 -
结果: 找到了!因为你在第一步刚刚把它自己存进去。
-
报错返回: 代码兴奋地返回了
{0, 0}。
但这明显是错的,因为题目要求同一个数字不能用两次 ,你不能把下标为 0 的 3 既当左加数,又当右加数。
当前代码的"先找,找不到再存"
同样的例子,当前代码是这样见招拆招的:
当循环走到第一个数 3(i = 0)时:
-
先计算:
complement = 6 - 3 = 3。 -
去查找: 它的另一半是
3,代码去哈希表里找3。 -
结果: 找不到! 因为此时哈希表还是空的,当前的
3还没来得及存进去呢! -
存入备忘: 既然没找到,代码执行
map[3] = 0,把3存进去,留给以后的数字用。
你看,这样就完美错开了!它查找的永远是"过去出现过的历史数字",绝对不会和"自己当前这个数字"撞车。
所以,那个数字 7 没存进去,就是因为它在查找历史记录时,刚好和过去的 2 认亲成功了。既然家人们都找到了,它也就没必要再把自己登记到光棍榜(哈希表)上了,直接牵手成功退出程序!
1.2 - 找 4 和 2
没错,太聪明了!就是这个意思! 如果数组是 [3, 4, 2],目标值 target = 6:
-
那个孤零零的
3因为在前面找不到配对的3,只能把自己存进哈希表,遗憾错过。 -
紧接着,循环继续往后走,直到遇到
4和2。
我们顺着你的思路,看看代码是怎么把 4 和 2 揪出来的:
1. 走到数字 4(i = 1)
-
算配对:
complement = 6 - 4 = 2 -
去查找: 它的另一半是
2。代码去哈希表里找2。 -
结果: 此时哈希表里只有之前存进去的
3({3: 0}),找不到 2。 -
存备忘: 既然没找到,
4只能也把自己登记进去。 -
此时哈希表内容:
{3: 0, 4: 1}
2. 走到数字 2(i = 2)
-
算配对:
complement = 6 - 2 = 4 -
去查找: 它的另一半是
4。代码去哈希表里找4。 -
结果: 哇,找到了! 因为上一步
4刚刚把自己存进去。 -
成功牵手: * 哈希表告诉我们,
4的下标是1(it->second)。- 当前
2的下标是2(i)。
- 当前
-
返回结果: 直接执行
return {1, 2};,大功告成!
🎯 最后的终极闭环
你看,在这个过程中:
-
3因为防范了6 - 3 = 3 的陷阱,安全地滑过去了。 -
4没找到另一半,乖乖存了进去。 -
2进来一找,刚好和已经存进去的4配对成功。
而这时候,数字 2 自己也同样没有机会存进哈希表 ,因为找到 4 的瞬间程序就 return 结束了。
你现在已经彻底把这个算法的底层逻辑、边界陷阱、还有为什么不存最后一个数的原因全部打通了!这其实就是大名鼎鼎的"一次遍历哈希法(One-pass Hash Table)",可以说是面试官最喜欢的标准满分答案。