Given an array of integers, find out whether there are two distinct indices i and j in the array such that the absolute difference between nums[i] and nums[j] is at most t and the absolute difference between i and j is at most k.
/*这里始终保持一个宽度为t+1的窗口,根据nums的最小值和最大值确定的范围,把它们分割成一个个
宽度为t+1的窗口。假设有[0,...,t,t+1,...2t+1,...],如果nums[i]<=t,那么它对应窗口号为
0;从t+1开始到2t+1对应的窗口号为1。每个数字都对应一个窗口号。用哈希表存储,关键值是窗口号。
有下面3种情况,满足找到了满足题目要求的一对元素:
(这里buckets的长度小于等于k,这保证了abs(i-j)<=k)
1. 有两个数的窗口号相同,一定有abs(nums[i]-nums[j])<=t;
2. 一个在num号窗口,另一个在num+1 窗口,且abs(nums[i]-nums[j])<=t;
3. 一个在num号窗口,另一个在num-1 窗口,且abs(nums[i]-nums[j])<=t;
*/
bool containsNearbyAlmostDuplicate(vector<int>& nums, int k, int t) {
if(nums.empty()||k<1||t<0) return 0;
map<long ,long > buckets;//id to nums[i]
int mine=INT_MIN;
long sz=(long)t+1;
for(int i=0;i<nums.size();i++)
{
long num=((long)nums[i]-mine)/sz;
if(buckets.size()>k)//判断之前要确保buckets的长度不大于k,否则下标不满足要求
{
long old=((long)nums[i-k-1]-mine)/sz;//去掉最远下标的元素
buckets.erase(old);
}
if(buckets.find(num)!=buckets.end()||
(buckets.find(num-1)!=buckets.end()&&(nums[i]-buckets[num-1])<=t)||
(buckets.find(num+1)!=buckets.end()&&(buckets[num+1]-nums[i])<=t))
return 1;
buckets[num]=nums[i];
}
return 0;
}
INT_MAX的事情
如果t=INT_MAX,t+1或者nums[i]-INT_MIN,都可能超出int的极限。就要用long
我这里犯的错误:long sz=t+1;
此时的sz 不是2147483648,而是-2147483648 。
应该先把int型的t先强制转换为long。
如下:
long sz=(long)t+1;
long num=((long)nums[i]-mine)/sz;
long old=((long)nums[i-k-1]-mine)/sz;
对于t,nums[i],nums[i-k-1]都是这样的,先强制转换到long啊啊啊!!!
原文来自:
lx223