|
| 1 | +### 题目描述 |
| 2 | + |
| 3 | +这是 LeetCode 上的 **[219. 存在重复元素 II](https://leetcode-cn.com/problems/contains-duplicate-ii/solution/gong-shui-san-xie-hua-dong-chuang-kou-yu-q02i/)** ,难度为 **简单**。 |
| 4 | + |
| 5 | +Tag : 「滑动窗口」、「哈希表」 |
| 6 | + |
| 7 | + |
| 8 | + |
| 9 | +给你一个整数数组 `nums` 和一个整数 `k` ,判断数组中是否存在两个 不同的索引 `i` 和 `j` ,满足 `nums[i] == nums[j]` 且 `abs(i - j) <= k` 。如果存在,返回 `true` ;否则,返回 `false` 。 |
| 10 | + |
| 11 | +示例 1: |
| 12 | +``` |
| 13 | +输入:nums = [1,2,3,1], k = 3 |
| 14 | +
|
| 15 | +输出:true |
| 16 | +``` |
| 17 | +示例 2: |
| 18 | +``` |
| 19 | +输入:nums = [1,0,1,1], k = 1 |
| 20 | +
|
| 21 | +输出:true |
| 22 | +``` |
| 23 | +示例 3: |
| 24 | +``` |
| 25 | +输入:nums = [1,2,3,1,2,3], k = 2 |
| 26 | +
|
| 27 | +输出:false |
| 28 | +``` |
| 29 | + |
| 30 | +提示: |
| 31 | +* $1 <= nums.length <= 10^5$ |
| 32 | +* $-10^9 <= nums[i] <= 10^9$ |
| 33 | +* $0 <= k <= 10^5$ |
| 34 | + |
| 35 | +--- |
| 36 | + |
| 37 | +### 滑动窗口 + 哈希表 |
| 38 | + |
| 39 | +整理题意:是否存在长度不超过的 $k + 1$ 窗口,窗口内有相同元素。 |
| 40 | + |
| 41 | +我们可以从前往后遍历 $nums$,同时使用 `Set` 记录遍历当前滑窗内出现过的元素。 |
| 42 | + |
| 43 | +假设当前遍历的元素为 $nums[i]$: |
| 44 | + |
| 45 | +* 下标小于等于 $k$(起始滑窗长度还不足 $k + 1$):直接往滑窗加数,即将当前元素加入 `Set` 中; |
| 46 | +* 下标大于 $k$:将上一滑窗的左端点元素 $nums[i - k - 1]$ 移除,判断当前滑窗的右端点元素 $nums[i]$ 是否存在 `Set` 中,若存在,返回 `True`,否则将当前元素 $nums[i]$ 加入 `Set` 中。 |
| 47 | + |
| 48 | +重复上述过程,若整个 $nums$ 处理完后仍未找到,返回 `False`。 |
| 49 | + |
| 50 | +**代码(感谢 [@Benhao](/u/himymben/) 同学提供的其他语言版本):** |
| 51 | +```Java |
| 52 | +class Solution { |
| 53 | + public boolean containsNearbyDuplicate(int[] nums, int k) { |
| 54 | + int n = nums.length; |
| 55 | + Set<Integer> set = new HashSet<>(); |
| 56 | + for (int i = 0; i < n; i++) { |
| 57 | + if (i > k) set.remove(nums[i - k - 1]); |
| 58 | + if (set.contains(nums[i])) return true; |
| 59 | + set.add(nums[i]); |
| 60 | + } |
| 61 | + return false; |
| 62 | + } |
| 63 | +} |
| 64 | +``` |
| 65 | +- |
| 66 | +```Python3 |
| 67 | +class Solution: |
| 68 | + def containsNearbyDuplicate(self, nums: List[int], k: int) -> bool: |
| 69 | + n = len(nums) |
| 70 | + s = set() |
| 71 | + for i in range(n): |
| 72 | + if i > k: |
| 73 | + s.remove(nums[i - k - 1]) |
| 74 | + if nums[i] in s: |
| 75 | + return True |
| 76 | + s.add(nums[i]) |
| 77 | + return False |
| 78 | +```` |
| 79 | +- |
| 80 | +```Go |
| 81 | +func containsNearbyDuplicate(nums []int, k int) bool { |
| 82 | + n := len(nums) |
| 83 | + set := map[int]bool{} |
| 84 | + for i := 0; i < n; i++ { |
| 85 | + if i > k { |
| 86 | + set[nums[i - k - 1]] = false |
| 87 | + } |
| 88 | + if set[nums[i]] { |
| 89 | + return true |
| 90 | + } |
| 91 | + set[nums[i]] = true |
| 92 | + } |
| 93 | + return false |
| 94 | +} |
| 95 | +``` |
| 96 | +* 时间复杂度:$O(n)$ |
| 97 | +* 空间复杂度:$O(k)$ |
| 98 | + |
| 99 | +--- |
| 100 | + |
| 101 | +### 最后 |
| 102 | + |
| 103 | +这是我们「刷穿 LeetCode」系列文章的第 `No.219` 篇,系列开始于 2021/01/01,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先把所有不带锁的题目刷完。 |
| 104 | + |
| 105 | +在这个系列文章里面,除了讲解解题思路以外,还会尽可能给出最为简洁的代码。如果涉及通解还会相应的代码模板。 |
| 106 | + |
| 107 | +为了方便各位同学能够电脑上进行调试和提交代码,我建立了相关的仓库:https://github.com/SharingSource/LogicStack-LeetCode 。 |
| 108 | + |
| 109 | +在仓库地址里,你可以看到系列文章的题解链接、系列文章的相应代码、LeetCode 原题链接和其他优选题解。 |
| 110 | + |
0 commit comments