剑指 Offer II 057. 值和下标之差都在给定的范围内
最简单的方法,两次遍历判断j-i<=k && Math.abs(nums[j] - nums[i]) <= t,存在这种情况直接return true
var containsNearbyAlmostDuplicate = function(nums, k, t) {
var len = nums.length;
for(var i =0;i<len;i++){
for(var j = i+1;j<len;j++){
if(j-i<=k && Math.abs(nums[j] - nums[i]) <= t){
return true
}
}
}
return false
};
方法二
- Math.abs(i-j)<=t,因此可以将数字放入若干大小为t+1的桶中
- 举例来说,将从0到t的数字放入编号为0的桶中,从t+1到2t+1的数字放入编号为1桶中,依此类推
- 如果两个数字被放入同人个桶中,那么它们的差的绝对值一定小于或等于t
- 具体逐一扫描数组中的数字,如果当前扫描的数字num,那么它将放入编号为id的桶中,如果这个桶中之前已经有数字,那么就找到两个差的绝对值小于或等于t的数字
- 如果桶中之前没有数字,则再判断编号为id-1和id-2的这两个相邻的桶中是否存在与num的差的绝对值小于或等于t的数字
- 因为其它桶中的数字与num的差的绝对值一定大于t,所以不需要判断其他的桶中是否有符合条件的数字
var containsNearbyAlmostDuplicate = function (nums, k, t) {
var buckets = new Map();
var bucketSize = t + 1;
var getBucketId = (num, bucketSize) => {
return num >= 0
? Math.floor(num / bucketSize)
: Math.floor((num + 1) / bucketSize) - 1;
};
for (var i = 0; i < nums.length; i++) {
var num = nums[i];
var id = getBucketId(num, bucketSize);
if (
buckets.has(id) ||
(buckets.has(id - 1) && buckets.get(id - 1) + t >= num) ||
(buckets.has(id + 1) && buckets.get(id + 1) - t <= num)
) {
return true;
}
buckets.set(id, num);
if (i >= k) {
buckets.delete(getBucketId(nums[i - k], bucketSize));
}
}
return false;
};