在问 · 算法题解

217. 存在重复元素

简单哈希表哈希集合力扣原题 ↗

题目描述

输入整数数组 nums。只要有某个值出现了两次或更多,就返回 true。

如果所有元素都不相同,返回 false。

示例 1
输入:nums = [1,2,3,1]
输出:true

解释:1 在下标 0 和 3 各出现一次。

示例 2
输入:nums = [1,2,3,4]
输出:false

解释:四个元素各不相同。

示例 3
输入:nums = [1,1,1,3,3,4,3,2,4,2]
输出:true

解释:1、2、3、4 都出现了不止一次。

数据范围

  • 1 <= nums.length <= 10^5
  • -10^9 <= nums[i] <= 10^9

解题思路:哈希集合

从左到右扫描,用哈希集合 seen 记住已经见过的数。读到 x 时先问「x 在 seen 里吗?」——在,说明前面出现过,立即返回 true;不在,就把 x 加入 seen 继续。扫完都没碰到重复,返回 false。

为什么正确

处理到下标 i 之前,seen 恰好是 nums[0..i-1] 中出现过的所有值,并且这些值两两不同。

复杂度分析

时间 O(n)(每个数一次 O(1) 平均的查询和插入),空间 O(n)。

易错点

必须先查再加:如果先 seen.add(x) 再判断 x in seen,每个数都会「撞上自己」而误判为 true。也可以排序后比较相邻元素(O(n log n)),但双重循环两两比较是 O(n²),会超时。

参考代码

Python、Java、C++、Go、JavaScript、TypeScript 六种语言,逻辑一致。

class Solution:
    def containsDuplicate(self, nums: List[int]) -> bool:
        seen = set()
        for x in nums:
            if x in seen:
                return True
            seen.add(x)
        return False

载入编辑器,自己跑一遍 →

其他解法

排序把重复元素变成相邻元素,用时间换空间;哈希集合用 O(n) 空间做到平均 O(n) 时间,并且能在遇到第一个重复元素时提前结束。

解法 2:排序 时间 O(n log n),空间 O(log n)

先对数组排序,相同的元素会排在一起。再扫描一遍,只要有相邻两个元素相等就返回 true。

不需要哈希表,额外空间只有排序的递归栈。时间多一个 log 因子,而且会打乱原数组的顺序。

from typing import List

class Solution:
    def containsDuplicate(self, nums: List[int]) -> bool:
        nums.sort()
        for i in range(1, len(nums)):
            if nums[i] == nums[i - 1]:
                return True
        return False

哈希表 专题的其他题目

查看 哈希表 全部题目 →