https://leetcode-cn.com/problems/contains-duplicate-iii/
思路一:
a
b
s
(
i
−
j
)
<
=
k
abs(i-j)<=k
abs(i−j)<=k很容易做到,只要我们按照区间处理元素即可。现在考虑第一个条件,如果我们保证元素有序(从小到大),那么只要任意两个相邻元素之差
<
=
t
<=t
<=t即可。不难想到用
s
e
t
set
set维护。
class Solution {
private:
set<int> s;
bool check(int val,int t)
{
auto it=s.lower_bound(val);
if(it!=s.end()&&(long long)*it-val<=t)
return 1;
if(it!=s.begin()&&(long long)val-*(--it)<=t)
return 1;
return 0;
}
public:
bool containsNearbyAlmostDuplicate(vector<int>& nums, int k, int t) {
int n=nums.size();
for(int i=min(n-1,k);i>=0;i--)
{
if(check(nums[i],t))
return 1;
s.insert(nums[i]);
}
for(int i=k+1;i<n;i++)
{
s.erase(nums[i-k-1]);
if(check(nums[i],t))
return 1;
s.insert(nums[i]);
}
return 0;
}
};
思路二:按照 … [ − 2 ∗ t , − t ) 、 [ − t 、 0 ) 、 [ 0 , t ) 、 [ t , 2 ∗ t ) … …[-2*t,-t)、[-t、0)、[0,t)、[t,2*t)… …[−2∗t,−t)、[−t、0)、[0,t)、[t,2∗t)…给整数分成一个个桶,用哈希表存储桶的编号,然后就和思路一比较类似了。
class Solution {
private:
unordered_map<int,int> table;
int getidx(int v,int t)
{
if(!t)
return v;
return v>=0?v/t:(v+1)/t-1;
}
bool check(int v,int t)
{
int id=getidx(v,t);
for(int i=-1;i<=1;i++)
{
auto it=table.find((long long)id+i);
if(it!=table.end()&&abs((long long)it->second-v)<=t)
return 1;
}
table[id]=v;
return 0;
}
public:
bool containsNearbyAlmostDuplicate(vector<int>& nums, int k, int t) {
int n=nums.size();
for(int i=min(n-1,k);i>=0;i--)
if(check(nums[i],t))
return 1;
for(int i=k+1;i<n;i++)
{
table.erase(getidx(nums[i-k-1],t));
if(check(nums[i],t))
return 1;
}
return 0;
}
};