基本原理是:将扫描过的最后k个元素(在一开始时,二叉查找树的大小是由1变化到k,然后保持k不变)放入二叉查找树这个有序的数据结构,利用其两个成员函数
set1.lower_bound(nums[i]);
set1.upper_bound(nums[i]);
lower_bound(nums[i]) : 大于等于nums[i]的第一个元素。
upper_bound(nums[i]):大于nums[i]的第一个元素。
具体函数特性见下方参考资料
在logk时间内分别找到大于等于nums[i]和大于nums[i]的值(在STL里set是由二叉查找树实现的),以找到nums[i]前k个中与nums[i]最近的数(lower_bound用于找最近的大于等于nums[i]的数;upper_bound用于找最近的小于等于nums[i]的数,注意upper_bound函数的功能是找到大于nums[i]的数)。
运行时间复杂度是o(nlgk)
这种将扫描过的元素放到某种数据结构以利用数据结构的某种功能达到某种目的的思想并不陌生,可是仍然没有想到。哎。。。 |
c++代码如下
class Solution {
public:
bool containsNearbyAlmostDuplicate(vector<int>& nums, int k, int t) {
set<long> set1;
set<long>::iterator iterLow;
set<long>::iterator iterUp;
for(int i = 0; i < nums.size(); i++) {
if(set1.size() == k + 1) set1.erase(set1.find(nums[i - (k + 1)]));
iterLow=set1.lower_bound(nums[i]);
if(iterLow != set1.end() && (*iterLow - nums[i]) <= t) return true;
iterUp=set1.upper_bound(nums[i]);
if(iterUp != set1.begin() && (nums[i] - *(--iterUp)) <= t) return true;
set1.insert(nums[i]);
}
return false;
}
};
参考http://www.cnblogs.com/easonliu/p/4544073.html
http://www.cplusplus.com/reference/set/set/lower_bound/
http://www.cplusplus.com/reference/set/set/upper_bound/