桶思想

桶思想

班级里有 n n n个同学,每个同学都有一个生日,老师想快速的知道有没有人的生日间隔在一个月内,该怎么做呢?

把每年365天分成12个月(就相当于12个桶),每个月(桶)内的生日都是满足的,并且相邻两个月也可能满足,除了这两种情况都不满足了。这就是桶思想

例题

LeetCode 220

我们将整数范围内的值按照绝对值不大于 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;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值