桶思想
班级里有 n n n个同学,每个同学都有一个生日,老师想快速的知道有没有人的生日间隔在一个月内,该怎么做呢?
把每年365天分成12个月(就相当于12个桶),每个月(桶)内的生日都是满足的,并且相邻两个月也可能满足,除了这两种情况都不满足了。这就是桶思想。
例题
我们将整数范围内的值按照绝对值不大于 t t t分桶,我们发现桶的大小为 t + 1 t+1 t+1即可,并且桶的元素最多有一个,因此我们可以使用哈希表实现。
特别的,注意计算桶的编号,负数需要先加 1 1 1再减去 1 1 1,保证结果计算正确。
typedef long long ll;
class Solution
{
public:
ll getID(ll val, int w)
{
return val >= 0 ? val / w : (val + 1) / w - 1;
}
bool containsNearbyAlmostDuplicate(vector<int> &nums, int k, int t)
{
unordered_map<ll, ll> buckets;
int l = 0;
int r = 0;
while (r < nums.size())
{
ll id = getID(nums[r], t + 1ll);
if (r - l > k)
{
buckets.erase(getID(nums[l], t + 1ll));
l++;
}
if (buckets.count(id))
{
return true;
}
if (buckets.count(id - 1) && abs(buckets[id - 1] - nums[r]) <= t)
{
return true;
}
if (buckets.count(id + 1) && abs(buckets[id + 1] - nums[r]) <= t)
{
return true;
}
buckets[id] = nums[r];
r++;
}
return false;
}
};