【面试经典150 | 哈希表】存在重复元素 II

文章目录

Tag

【哈希表】【滑动窗口】【数组】


题目来源

219. 存在重复元素 II


题目解读

判断在数组中有没有相同的元素小于一定的距离。


解题思路

方法一:哈希表

我们维护一个哈希表来记录数组中的元素以及上一次出现的位置,如果上一次出现的位置和这一次出现的位置之差小于等于 k,那就返回 true,否则返回 false

实现代码

cpp 复制代码
class Solution {
public:
    bool containsNearbyDuplicate(vector<int>& nums, int k) {
        int n = nums.size();

        unordered_map<int, int> mp;
        for (int i = 0; i < n; ++i) {
            if (mp.count(nums[i]) && (i - mp[nums[i]] <= k)) {
                return true;
            }
            mp[nums[i]] = i;
        }
        return false;
    }
};

复杂度分析

时间复杂度: O ( n ) O(n) O(n), n n n 为数组 nums 的长度。

空间复杂度: O ( n ) O(n) O(n),使用哈希表记录数组中元素上一次出现的位置。

方法二:滑动窗口

换一个思路,我们只要判断在长度为 k 的窗口中是否有重复的元素出现即可。在滑窗没满之前,就向滑窗中加入元素,加入之前判断滑窗内是否有当前要加入的元素,如果有,直接返回 false;当滑窗满了,滑动滑窗,当前的 nums[i] 要进入滑窗,那么 nums[i - k - i] 要退出滑窗,判断滑窗内是否有当前要加入的元素,如果有,直接返回 false

如果滑窗滑到数组末尾,都没有返回 true,就返回 false

实现代码

cpp 复制代码
class Solution {
public:
    bool containsNearbyDuplicate(vector<int>& nums, int k) {
        unordered_set<int> s;
        int n = nums.size();
        for (int i = 0; i < n; ++i) {
            if (i > k) {
                s.erase(nums[i - k - 1]);
            }
            if (s.count(nums[i])) return true;
            s.emplace(nums[i]);
        }
        return false;
    }
};

时间复杂度: O ( n ) O(n) O(n), n n n 为数组 nums 的长度。

空间复杂度: O ( k ) O(k) O(k),使用无序集合记录滑窗中的元素。


其他语言

python3+哈希表

python3 复制代码
class Solution:
    def containsNearbyDuplicate(self, nums: List[int], k: int) -> bool:
        pos = {}
        for i, num in enumerate(nums):
            if num in pos and i - pos[num] <= k:
                return True
            pos[num] = i
        return False

python3+滑动窗口

python3 复制代码
class Solution:
    def containsNearbyDuplicate(self, nums: List[int], k: int) -> bool:
        s = set()
        for i, num in enumerate(nums):
            if i > k:
                s.remove(nums[i - k - 1])
            if num in s:
                return True
            s.add(num)
        return False

写在最后

如果文章内容有任何错误或者您对文章有任何疑问,欢迎私信博主或者在评论区指出 💬💬💬。

如果大家有更优的时间、空间复杂度方法,欢迎评论区交流。

最后,感谢您的阅读,如果感到有所收获的话可以给博主点一个 👍 哦。

相关推荐
Q741_1479 小时前
C++ 力扣 438.找到字符串中所有字母异位词 题解 优选算法 滑动窗口 每日一题
c++·算法·leetcode·双指针·滑动窗口
Tisfy1 天前
LeetCode 837.新 21 点:动态规划+滑动窗口
数学·算法·leetcode·动态规划·dp·滑动窗口·概率
KarrySmile2 天前
Day8--滑动窗口与双指针--1004. 最大连续1的个数 III,1658. 将 x 减到 0 的最小操作数,3641. 最长半重复子数组
数据结构·算法·双指针·滑动窗口·不定长滑动窗口·最大连续1的个数·最长子数组
伟大的车尔尼2 天前
滑动窗口题目:字符串的排列
滑动窗口
ankleless4 天前
C语言(11)—— 数组(超绝详细总结)
c语言·零基础·数组·二维数组·自学·一维数组
呼啦啦啦啦啦啦啦啦5 天前
【Java】HashMap的详细介绍
java·数据结构·哈希表
梁辰兴6 天前
数据结构:串、数组与广义表
开发语言·数据结构·c··数组·广义表
珍珠是蚌的眼泪10 天前
LeetCode_哈希表
leetcode·哈希表·快乐数·字母异位词
没有bug.的程序员10 天前
《常见高频算法题 Java 解法实战精讲(1):链表与数组》
java·算法·链表·数组
崎岖Qiu12 天前
leetcode1343:大小为K的子数组(定长滑动窗口)
java·算法·leetcode·力扣·滑动窗口