217. 存在重复元素(简单)
Blind 75 › 217. 存在重复元素(简单) (第 1 章)
题目
给定一个整数数组,判断其中是否存在某个数值至少出现两次:有就返回 true,所有元素互不相同则返回 false。
自造示例:[3,1,4,3,5] → true(3 在下标 0 和 3 各出现一次);[2,0,-2,9] → false(两两都不同)。
约束:数组长度 1 ~ 105;元素为 32 位整数,可取负数,范围约 -109 ~ 109。
思路
一句话:判断“这个数以前有没有出现过”——出现过,就是重复。
最直白的做法:对每个元素,回头和它前面的所有元素逐个比较,一旦相等就返回 true。这需要两层循环,最坏比较 O(n²) 次;当 n = 105 时会达到上百亿次,直接超时。
想更快,先想到排序:排好序后,相同的数必然相邻,扫一遍比较邻居即可,时间 O(n log n)。这已经能通过,但判断“是否重复”其实还有更优解。
关键观察:判重本质是成员查询——“x 是否已经见过”。用一个哈希集合记录见过的元素,查询和插入的平均代价都是 O(1),于是整个判断降到 O(n)。
为什么必须用哈希集合而不是普通列表?列表的 in 查询要逐个扫描,是 O(n),总时间又变回 O(n²);哈希集合才是 O(1) 平均查询。另外,元素有负数且范围达到 109,没法用一个很小的布尔桶数组,集合天然适配任意整数。
解法
维护一个哈希集合 seen,从左到右遍历:
- 若
nums[i]已在seen中,立即返回true。 - 否则把它加入
seen,继续下一个。 - 遍历结束仍没返回,说明没有重复,返回
false。
| 当前元素 | 已见集合 | 动作 |
|---|---|---|
| 3 | {} | 不在,加入 → {3} |
| 1 | {3} | 不在,加入 → {3,1} |
| 4 | {3,1} | 不在,加入 → {3,1,4} |
| 3 | {3,1,4} | 已在 → 返回 true |
整个过程只需一遍遍历,且发现重复后立刻停止,不会做多余工作。
下图把上面 3 个步骤串成流程,并逐步演示:


C++
class Solution {
public:
bool containsDuplicate(vector<int>& nums) {
unordered_set<int> seen;
for (int x : nums) {
if (seen.f本篇为付费内容
您已阅读试读部分,购买后即可解锁全文。
⚠️ 本站内容已做唯一性标记并受版权保护,未经授权禁止转载,侵权必究。
还没有评论,来说两句?