力扣刷题#6:LeetCode349两个数组的交集_从"不知道怎么求"到"一行思路就够"
有时候,思路就差一层窗户纸。捅破了发现,代码自己就出来了。
题目
给定两个数组,返回它们的交集。
输入: nums1 = [1,2,2,1], nums2 = [2,2]
输出: [2]
注意:结果中每个元素是唯一的,不考虑顺序。
卡住的地方
我知道暴力是 O(n²),想优化但不知道用什么。
第一反应是 set——因为交集结果只会比最小的数组还小。但怎么求?我不知道。
最初的想法走偏了:"遍历第二个数组,不在 set 中的就丢掉,剩下的就是交集。"——思路反了。
后来被点醒:不是丢掉不在的,而是捡起在的。
思路一步步成型
第一步:把 nums1 的所有元素扔进一个 unordered_set
→ set = {1, 2}(自动去重)
第二步:遍历 nums2,对每个元素检查在不在 set 里
在 → 这就是交集的一部分,记下来
不在 → 跳过
第三步:还要去重
nums2 如果有重复的 2,不能往结果里存两次
解决方案:找到一个交集后,从 set 里删掉它
这样下次再遇到同样的数,在 set 里找不到了,就不会重复存
我的代码
class Solution {
public:
vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
unordered_set<int> n;
vector<int> res;
// 第一步:nums1 的元素全存进 set
for (int i = 0; i < nums1.size(); i++) {
n.insert(nums1[i]);
}
// 第二步:遍历 nums2,在 set 里的就是交集
for (int i = 0; i < nums2.size(); i++) {
if (n.find(nums2[i]) != n.end()) {
n.erase(nums2[i]); // 删掉,防止重复
res.push_back(nums2[i]);
}
}
return res;
}
};
踩的坑
1. find 的返回值不能当布尔直接用
// 错误写法——编译不过
if (n.find(x))
// 正确写法
if (n.find(x) != n.end()) // 找到了
if (n.find(x) == n.end()) // 没找到
2. vector 追加元素用 push_back,不是 insert
res.insert(x); // ❌ vector 没有这个单参数 insert
res.push_back(x); // ✅ 追加到末尾
3. 结果去重
如果 nums2 有重复,不处理的话结果里也会重复。删 set 元素(erase)是最简单的去重方式:找到一个就删掉,下次再遇到就找不到了。
扩展:vector 常用操作
vector 是以后刷题用得最多的容器,没有之一。
vector<int> v; // 声明空的 vector
vector<int> v(10); // 声明 10 个元素,默认 0
vector<int> v = {1,2,3}; // 声明并初始化
// 增
v.push_back(x); // 末尾追加
v.insert(v.begin(), x); // 开头插入(慢,不推荐)
v.insert(v.begin() + i, x); // 指定位置插入
// 删
v.pop_back(); // 删除末尾
v.erase(v.begin() + i); // 删除指定位置
// 查
v[i] // 直接下标访问(O(1))
v.size() // 元素个数
v.empty() // 是否为空
v.begin() // 起始迭代器
v.end() // 末尾迭代器
// 改
v[i] = x; // 下标修改
sort(v.begin(), v.end());// 排序(需要 #include <algorithm>)
刷题够用的就这些,其他的遇到再查。
扩展:set 家族全家桶
| 容器 | 特点 | 查找 | 插入 | 删除 | 用在哪 |
|---|---|---|---|---|---|
unordered_set |
无序、O(1) | find |
insert |
erase |
只要判断存在,不关心顺序 |
set |
有序(红黑树)、O(log n) | find |
insert |
erase |
需要自动排序 |
unordered_multiset |
无序、可重复 | find |
insert |
erase |
允许重复值,不计次数 |
multiset |
有序、可重复 | find |
insert |
erase |
有序且允许重复 |
刷题时 90% 的情况用 unordered_set,因为它最快(O(1))。只有题目要求顺序时才用 set。
特别提醒:unordered_set 的 erase(x) 会删除所有值为 x 的元素。但我们的场景正好用上这个特性——删了就不会再被找到了,实现自动去重。
学到了什么
- 思路比语法重要——知道"用 set 存第一个,遍历第二个查"这个思路后,代码自然就写出来了。
- STL 语法是熟练活——
find != end、push_back、erase,多写几次就变成肌肉记忆了。 - 去重不一定需要第二个 set——找到一个就
erase掉,一句代码搞定去重。
本文档有 AI 辅助生成,作者提供问题和思路,综合获得以上内容。

浙公网安备 33010602011771号