Contains Duplicate II
You're given an integer array nums and an integer k. Return true if two different indices i and j hold the same value with abs(i - j) <= k, meaning some value repeats within k positions of itself. Return false otherwise, including when every repeat is more than k positions apart. With k = 0 the answer is always false.
Examples
nums = [1,2,3,1], k = 3 returns true
The two 1s sit at indices 0 and 3, exactly 3 positions apart.
nums = [1,0,1,1], k = 1 returns true
The 1s at indices 0 and 2 are too far apart, but the 1s at indices 2 and 3 are adjacent.
nums = [1,2,3,1,2,3], k = 2 returns false
Every value repeats, but each repeat is 3 positions after the first copy, which is more than k.
Constraints
- 1 <= nums.length <= 10^5
- -10^9 <= nums[i] <= 10^9
- 0 <= k <= 10^5
Hints
For a value at index i, which earlier indices could possibly be its partner?
Keep a hash set of the last k values seen, sliding it forward as you go.
For each i: if nums[i] is in the set, return true. Add nums[i]. If the set's size is now greater than k, remove nums[i - k]. Return false after the loop.
Drill This: Your Approach First
Approach
A match for index i can only come from the k indices just before it, so keep those values in a hash set that acts as a sliding window. At each index, if the value is already in the set, a repeat lies within k positions: return true. Otherwise add it, and once the set holds more than k values, remove nums[i - k], which is now too far back to matter. The set never holds duplicates, since a duplicate would have returned already, so its size tracks the window exactly.
Time
O(n)
Space
O(min(n, k))
Pitfall
Solutions
class Solution {
public boolean containsNearbyDuplicate(int[] nums, int k) {
Set<Integer> window = new HashSet<>();
for (int i = 0; i < nums.length; i++) {
if (!window.add(nums[i])) return true;
if (window.size() > k) window.remove(nums[i - k]);
}
return false;
}
}class Solution:
def containsNearbyDuplicate(self, nums, k: int) -> bool:
window = set()
for i, n in enumerate(nums):
if n in window:
return True
window.add(n)
if len(window) > k:
window.remove(nums[i - k])
return False