思路:滑动窗口
class Solution {
public:
bool containsNearbyAlmostDuplicate(vector<int>& nums, int k, int t) {
int i=0;//作为窗口的最左界限
set<int> m;//作为滑动窗口的容器
for(int j=0;j<nums.size();++j)
{
//max函数是为了考虑越界问题
//lower_bound函数是取得大于等于当前值的迭代器,若没有这样的值,则返回end()
//找到大于等于nums[j]-t的最小值
auto sit=m.lower_bound(max(nums[j],INT_MIN+t)-t);
//判断找到的值是否符合要求
//1.有这样的值,即不为end()
//2.它的值的大小是小于nums[j]+t的,同样这里考虑了溢出
//由于上面取得是大于等于nums[j]-t的
//两个条件重叠就是处于nums[j]-t~nums[j]+t之间
if(sit!=m.end()&&*sit<=min(nums[j],INT_MAX-t)+t)
return true;
//将当前值送入滑动窗口
m.insert(nums[j]);
//此时j以及超过滑动窗的大小,所以每进来一个值就要除去一个值
if(j>=k)//注意这里的等号
m.erase(nums[i++]);
}
return false;
}
};
注意,即使存在相等的元素对于set容器来说也是可以的,因为他是先找再放入滑动窗口的,所以当找到一个大于等于某元素是,就会满足条件,直接返回了true,所以,用set容器并不因为存在相同元素而影响结果。
补充两个函数:
头文件
lower_bound( begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于或等于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
upper_bound( begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。