220. Contains Duplicate III
Given an array of integers, find out whether there are two distinct indices i and j in the array such that the difference between nums[i] and nums[j] is at most t and the difference between i and j is at most k.
O(nlogn) using set:
public class Solution {
public boolean containsNearbyAlmostDuplicate(int[] nums, int k, int t) {
if (nums.length==0 || k<=0 || t<0) return false;
TreeSet<Integer> set= new TreeSet<>();
for (int i = 0; i < nums.length; i++) {
Integer upper= set.floor(nums[i]+t);
Integer lower= set.ceiling(nums[i]-t);
if ((upper !=null && upper>= nums[i])|| (lower != null && lower<=nums[i]))
return true;
if (i>=k) set.remove(nums[i-k]);
set.add(nums[i]);
}
return false;
}
}
better: O(n) using bucket
public class Solution {
public boolean containsNearbyAlmostDuplicate(int[] nums, int k, int t) {
if (nums.length==0 || k<=0 || t<0) return false;
Map<Long, Long> map= new HashMap<>();
for (int i = 0; i < nums.length; i++) {
long invertnum= (long) nums[i]- Integer.MIN_VALUE;
long bucket= invertnum/((long)t+1);
if (map.containsKey(bucket) || (map.containsKey(bucket-1) && invertnum-map.get(bucket-1)<=t)
|| (map.containsKey(bucket+1) && map.get(bucket+1)-invertnum<=t))
return true;
if (i>=k){
long last= ((long)nums[i-k]- Integer.MIN_VALUE) / ((long)t+1);
map.remove(last);
}
map.put(bucket, invertnum);
}
return false;
}
}