image.png

解题思路

Set 滑动窗口

如果在数组中有两个元素都为v,并且距离在k以内就返回true
image.png
这样的结果一定在一个长度为k+1的区间中,左区间l,右区间k。
image.png
即如果在长度为k+1的区间内如果能找到两个相等的元素,那么这两个元素的差一定也是小于等于k的

因此问题变为能否在nums数组中找到一个长度为k+1的区间,其中有两个元素值相等
变为滑动窗口问题**

  • 如果有两个一样的元素,直接返回
  • 如果没有,看下一个元素,并且减去窗口的第一个元素

image.png

  • 看新的元素在新的数组中是否有一样的元素

image.png

  • 如果没有,将其纳入新的区间,右区间++,得到一个没有重复元素的新的区间

image.png

因为只需要看有没有一样的元素,查找表使用set
滑动窗口的长度等于set的长度

  1. public boolean containsNearbyDuplicate(int[] nums, int k) {
  2. //建立一个set保存长度为k+1的数组中出现的元素
  3. Set<Integer> set = new HashSet<>();
  4. for(int i=0;i<nums.length;i++){
  5. //如果新的数在前面出现过 直接返回
  6. if(set.contains(nums[i]))
  7. return true;
  8. //如果没有出现过 将该数添加到窗口中
  9. set.add(nums[i]);
  10. //判断此时窗口的大小 如果已经等于k+1 需要删除最左侧的数 nums[i-k]
  11. //保持窗口中最多有k个元素
  12. if(set.size()==k+1)
  13. set.remove(nums[i-k]);
  14. }
  15. return false;
  16. }
  17. //time O(n)
  18. //space O(k)