问题背景
给你一个整数数组 n u m s nums nums 和一个整数 k k k,判断数组中是否存在两个 不同的索引 i i i 和 j j j,满足 n u m s [ i ] = n u m s [ j ] nums[i] = nums[j] nums[i]=nums[j] 且 ∣ i − j ∣ < = k |i - j| <= k ∣i−j∣<=k。如果存在,返回 t r u e true true;否则,返回 f a l s e false false。
数据约束
- 1 ≤ n u m s . l e n g t h ≤ 1 0 5 1 \le nums.length \le 10 ^ 5 1≤nums.length≤105
- − 1 0 9 ≤ n u m s [ i ] ≤ 1 0 9 -10 ^ 9 \le nums[i] \le 10 ^ 9 −109≤nums[i]≤109
- 0 ≤ k ≤ 1 0 5 0 \le k \le 10 ^ 5 0≤k≤105
解题过程
这题有两种思路,一是枚举右维护左,用哈希表来记录每个元素最后出现的位置,遇到新元素时,去哈希表中查出离当前位置最近的上一个位置,判断是否符合条件。
还可以从固定 k k k的角度出发,看作定长滑窗,同样定义一个哈希表,只要判断会不会出现窗口中存在重复元素的情况即可。
具体实现
枚举右维护左
class Solution {public boolean containsNearbyDuplicate(int[] nums, int k) {Map<Integer, Integer> map = new HashMap<>();for (int i = 0; i < nums.length; i++) {int cur = nums[i];if (map.containsKey(cur) && i - map.get(cur) <= k) {return true;}map.put(cur, i);}return false;}
}
定长滑窗
class Solution {public boolean containsNearbyDuplicate(int[] nums, int k) {Set<Integer> set = new HashSet<>();for (int i = 0; i < nums.length; i++) {if (!set.add(nums[i])) {return true;}if (i >= k) {set.remove(nums[i - k]);}}return false;}
}