image.png

解题思路

滑动窗口 set

保持一个滑动窗口[l,l+k]

image.png
对于一个新的元素
image.png
从这个窗口的左边减去一个元素
image.png
同时l++
image.png
然后对这个新的元素,在滑动窗口内寻找是否有满足题意的元素
即寻找 abs(v-x) < k 的元素
image.png
即寻找的元素的范围在[v-t,v+t]范围内
这里使用具有顺序性的treeset
image.png
ceil(v-t)表示大于等于v-t的最小元素 floor(v+t)表示小于等于v+t的最小元素
如果ceil(v-t)比v+t还要小,说明一定存在一个元素,满足题意
同理如果floor(v+t)比v-t还要小,说明一定存在一个元素,满足题意

这里使用java中的treeset保存有序的set
ceiling(i)表示比i大的最小的树

  1. public boolean containsNearbyAlmostDuplicate(int[] nums, int k, int t) {
  2. TreeSet<Long> record = new TreeSet<Long>();
  3. for(int i=0;i<nums.length;i++){
  4. //如果存在比nums[i]-t要大的数 并且该数 比nums[i]-t要小 则返回
  5. if(record.ceiling((long)nums[i]-(long)t)!=null &&record.ceiling((long)nums[i]-(long)t)<=(long)nums[i]+(long)t)
  6. return true;
  7. //加入一个有序的集合
  8. record.add((long)nums[i]);
  9. //维持窗口的大小
  10. if(record.size()==k+1)
  11. record.remove((long)nums[i-k]);
  12. }
  13. return false;
  14. }
  15. //使用long防止溢出
  16. //time:O(nlogn)
  17. //space: