219. 存在重复元素 II : 滑动窗口运用题

简介: 219. 存在重复元素 II : 滑动窗口运用题

网络异常,图片无法展示
|


题目描述



这是 LeetCode 上的 219. 存在重复元素 II ,难度为 简单


Tag : 「滑动窗口」、「哈希表」


给你一个整数数组 nums 和一个整数 k ,判断数组中是否存在两个 不同的索引 ij ,满足 nums[i] == nums[j]abs(i - j) <= k 。如果存在,返回 true ;否则,返回 false


示例 1:


输入:nums = [1,2,3,1], k = 3
输出:true
复制代码


示例 2:


输入:nums = [1,0,1,1], k = 1
输出:true
复制代码


示例 3:


输入:nums = [1,2,3,1,2,3], k = 2
输出:false
复制代码


提示:


  • 1 <= nums.length <= 10^51<=nums.length<=105
  • -10^9 <= nums[i] <= 10^9109<=nums[i]<=109
  • 0 <= k <= 10^50<=k<=105


滑动窗口 + 哈希表



整理题意:是否存在长度不超过的 k + 1k+1 窗口,窗口内有相同元素。


我们可以从前往后遍历 numsnums,同时使用 Set 记录遍历当前滑窗内出现过的元素。

假设当前遍历的元素为 nums[i]nums[i]


  • 下标小于等于 kk(起始滑窗长度还不足 k + 1k+1):直接往滑窗加数,即将当前元素加入 Set 中;
  • 下标大于 kk:将上一滑窗的左端点元素 nums[i - k - 1]nums[ik1] 移除,判断当前滑窗的右端点元素 nums[i]nums[i] 是否存在 Set 中,若存在,返回 True,否则将当前元素 nums[i]nums[i] 加入 Set 中。


重复上述过程,若整个 numsnums 处理完后仍未找到,返回 False


代码(感谢 @Benhao 同学提供的其他语言版本):


class Solution {
    public boolean containsNearbyDuplicate(int[] nums, int k) {
        int n = nums.length;
        Set<Integer> set = new HashSet<>();
        for (int i = 0; i < n; i++) {
            if (i > k) set.remove(nums[i - k - 1]);
            if (set.contains(nums[i])) return true;
            set.add(nums[i]);
        }
        return false;
    }
}
复制代码

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

func containsNearbyDuplicate(nums []int, k int) bool {
    n := len(nums)
    set := map[int]bool{}
    for i := 0; i < n; i++ {
        if i > k {
            set[nums[i - k - 1]] = false
        }
        if set[nums[i]] {
            return true
        }
        set[nums[i]] = true
    }
    return false
}
复制代码


  • 时间复杂度:O(n)O(n)
  • 空间复杂度:O(k)O(k)


最后



这是我们「刷穿 LeetCode」系列文章的第 No.219 篇,系列开始于 2021/01/01,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先把所有不带锁的题目刷完。


在这个系列文章里面,除了讲解解题思路以外,还会尽可能给出最为简洁的代码。如果涉及通解还会相应的代码模板。


为了方便各位同学能够电脑上进行调试和提交代码,我建立了相关的仓库:github.com/SharingSour…


在仓库地址里,你可以看到系列文章的题解链接、系列文章的相应代码、LeetCode 原题链接和其他优选题解。

相关文章
|
5月前
|
算法 测试技术 C++
【动态规划】【滑动窗口】【C++算法】 629K 个逆序对数组
【动态规划】【滑动窗口】【C++算法】 629K 个逆序对数组
|
3月前
|
C++
567. 字符串的排列(c++)滑动窗口
567. 字符串的排列(c++)滑动窗口
|
4月前
|
算法
双指针+滑动窗口
双指针+滑动窗口
|
5月前
|
算法 测试技术 Serverless
【二分查找】【C++算法】378. 有序矩阵中第 K 小的元素
【二分查找】【C++算法】378. 有序矩阵中第 K 小的元素
|
5月前
|
算法 测试技术 C#
【map】【滑动窗口】【优先队列】LeetCode480滑动窗口中位数
【map】【滑动窗口】【优先队列】LeetCode480滑动窗口中位数
|
5月前
|
搜索推荐 算法 测试技术
【排序算法】【二叉树】【滑动窗口】LeetCode220: 存在重复元素 III
【排序算法】【二叉树】【滑动窗口】LeetCode220: 存在重复元素 III
|
5月前
|
存储
【Leetcode 209】长度最小的子数组 —— 滑动窗口|双指针
我们可以使用双指针解决本题,定义两个指针 i 和 j 分别表示子数组(滑动窗口窗口)的开始位置和结束位置,维护变量 sum 存储子数组中的元素和。每一轮迭代中,每当 sum >= target 则记录子数组最小长度,移动慢指针。在每一轮迭代最后,移动快指针
|
5月前
|
算法
滑动窗口算法&删除排序数组中重复项
滑动窗口算法&删除排序数组中重复项
|
5月前
基础数据结构leetcode滑动窗口专题
基础数据结构leetcode滑动窗口专题
28 0
滑动窗口(单调队列)
滑动窗口(单调队列)
40 0