题目描述:
给你一个整数数组 nums
和两个整数 k
和 t
。请你判断是否存在 两个不同下标 i
和 j
,使得 abs(nums[i] - nums[j]) <= t
,同时又满足 abs(i - j) <= k
。
如果存在则返回 true
,不存在返回 false
。
详细步骤已经写在下面代码的注释里面:
class Solution {
long size;
public boolean containsNearbyAlmostDuplicate(int[] nums,int k, int t) {
int n = nums.length;
//定义桶
Map<Long, Long> map = new HashMap<>();
size = t + 1L;
for(int i=0;i<n;i++){
//找到nums[i]这个数据对应的桶下标
long u = nums[i]*1L;
long index = getIndex(u);
//桶里面有数据,同一个下标肯定满足abs(nums[i] - nums[j]) <= t
if(map.containsKey(index))return true;
//桶里面没有数据,我们就检查两边的桶,再往多两边就肯定不满足abs(i - j) <= k了
//所以判断两侧就行
long lmap = index - 1, rmap = index + 1;
//如果两侧桶里面有数据,那么就判断abs(nums[i] - nums[j]) <= t这个条件是否满足
if(map.containsKey(lmap) && u - map.get(lmap) <= t)return true;
if(map.containsKey(rmap) && map.get(rmap) - u <= t)return true;
//都不满足那我们就把这个元素放入桶就行了
map.put(index, u);
//当i>=k时,就要移除下标不在[i-k,i]范围的元素,就是
if(i>=k)map.remove(getIndex(nums[i-k]*1L));
}
//都不满足就没了
return false;
}
long getIndex(long u){
//u>=0时[0,1,2,3]需要在同一个桶,下标为u/size
//u<0时[-1,-2,-3,-4]需要在同一个桶,如果使用u/size,那么-4下标就是-1,其他三个就是0,不在同一个桶
//所以我们将负数的值都+1,让他们在同一个下标,但是下标0被正数使用,所以下标全部-1
return u>=0 ? (u/size) : ((u+1)/size) - 1;
}
}
- 时间复杂度:O(n)
- 空间复杂度:O(k)