题目:
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.
解答:
这一题有两个思路,都是参考discussion里写出来的。一个是bucket, 一个是TreeSet。
1.bucket是按照两个数最多相差t这个性质,把每个数分到不一样的bucket里,在k范围内,如果有两个数在同一个bucket里,那么说明这两个数满足条件;或者相邻的bucket里存在一个数,而且与这个数的差小于等于t,那这个数也满足;其它都是超出范围的。
public boolean containsNearbyAlmostDuplicate(int[] nums, int k, int t) {
if (k < 1 || t < 0) return false;
Map<Long, Long> map = new HashMap<>();
for (int i = 0; i < nums.length; i++) {
long remappedNum = (long) nums[i] - Integer.MIN_VALUE;
long bucket = remappedNum / ((long) t + 1);
if (map.containsKey(bucket) || (map.containsKey(bucket - 1) && remappedNum - map.get(bucket - 1) <= t) || (map.containsKey(bucket + 1) && map.get(bucket + 1) - remappedNum <= t)) {
return true;
}
if (map.entrySet().size() >= k) {
long lastBucket = ((long) nums[i - k] - Integer.MIN_VALUE) / ((long) t + 1);
map.remove(lastBucket);
}
map.put(bucket, remappedNum);
}
return false;
}
2.TreeSet是更加直接的用floor和ceiling来看有没有在这个范围内存在的数。
public boolean containsNearbyAlmostDuplicate(int[] nums, int k, int t) {
if (k < 1 || t < 0) return false;
TreeSet<Integer> values = new TreeSet<Integer>();
for (int i = 0; i < nums.length; i++) {
Integer floor = values.floor(nums[i] + t);
Integer ceiling = values.ceiling(nums[i] - t);
if ((floor != null && floor >= nums[i]) || (ceiling != null && ceiling <= nums[i])) {
return true;
}
if (values.size() >= k) {
values.remove(nums[i - k]);
}
values.add(nums[i]);
}
return false;
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。