解题思路
Set 滑动窗口
如果在数组中有两个元素都为v,并且距离在k以内就返回true
这样的结果一定在一个长度为k+1的区间中,左区间l,右区间k。
即如果在长度为k+1的区间内如果能找到两个相等的元素,那么这两个元素的差一定也是小于等于k的
因此问题变为能否在nums数组中找到一个长度为k+1的区间,其中有两个元素值相等
变为滑动窗口问题**
- 如果有两个一样的元素,直接返回
- 如果没有,看下一个元素,并且减去窗口的第一个元素
- 看新的元素在新的数组中是否有一样的元素
- 如果没有,将其纳入新的区间,右区间++,得到一个没有重复元素的新的区间
因为只需要看有没有一样的元素,查找表使用set
滑动窗口的长度等于set的长度
public boolean containsNearbyDuplicate(int[] nums, int k) {
//建立一个set保存长度为k+1的数组中出现的元素
Set<Integer> set = new HashSet<>();
for(int i=0;i<nums.length;i++){
//如果新的数在前面出现过 直接返回
if(set.contains(nums[i]))
return true;
//如果没有出现过 将该数添加到窗口中
set.add(nums[i]);
//判断此时窗口的大小 如果已经等于k+1 需要删除最左侧的数 nums[i-k]
//保持窗口中最多有k个元素
if(set.size()==k+1)
set.remove(nums[i-k]);
}
return false;
}
//time O(n)
//space O(k)