桶排序(Bucket Sort)

. - 力扣(LeetCode)

这道题可以使用桶排序来做

桶排序(Bucket Sort)是一种排序算法,其工作原理是将数组分到有限数量的桶子里。每个桶子再个别排序(有可能再使用别的排序算法或是以递归方式继续使用桶排序进行排序)。当要被排序的数组内的数值是均匀分配的时候,桶排序使用线性时间(Θ(n))。但桶排序并不是比较排序,它不受到O(n log n)下限的影响。

桶排序的核心在于合理设计桶的数量和每个桶的范围,使得数据能均匀分布到各个桶中,进而降低后续排序的复杂度。桶排序的步骤主要包括初始化桶确定桶的数量及每个桶对应的数据范围,遍历待排序序列将每个元素放入对应的桶中,以及对每个非空桶内部使用其他排序算法进行排序。

总的来说,桶排序是一个利用函数映射关系将数据分布到有限数量的桶中,再对每个桶内的数据进行排序,最后按顺序合并得到全局有序序列的排序算法。

官方给出的代码如下

class Solution {
    public boolean containsNearbyAlmostDuplicate(int[] nums, int k, int t) {
        int n = nums.length;
        Map<Long, Long> map = new HashMap<Long, Long>();
        long w = (long) t + 1;
        for (int i = 0; i < n; i++) {
            long id = getID(nums[i], w);
            if (map.containsKey(id)) {
                return true;
            }
            if (map.containsKey(id - 1) && Math.abs(nums[i] - map.get(id - 1)) < w) {
                return true;
            }
            if (map.containsKey(id + 1) && Math.abs(nums[i] - map.get(id + 1)) < w) {
                return true;
            }
            map.put(id, (long) nums[i]);
            if (i >= k) {
                map.remove(getID(nums[i - k], w));
            }
        }
        return false;
    }

    public long getID(long x, long w) {
        if (x >= 0) {
            return x / w;
        }
        return (x + 1) / w - 1;
    }
}

解释如下

  1. 使用一个HashMap(名为map)来存储数组元素的值及其对应的原始值。这个HashMap的键是数组元素的“桶”ID,值是数组元素的值。

  2. wt + 1,用作计算桶ID的间隔。桶的大小决定了算法对t的容忍度。

  3. 遍历数组nums,对于每个元素:

    • 使用getID方法计算元素的桶ID。
    • 检查当前元素的桶ID是否已经在map中存在,如果存在则说明找到了两个满足条件的元素,返回true
    • 检查当前元素的桶ID的相邻桶(即ID减1和ID加1)是否存在于map中,并且与当前元素的差的绝对值小于w。如果是,则说明找到了两个满足条件的元素,返回true
    • 将当前元素的桶ID和值(这里存储的是元素的值)放入map
    • 如果已经遍历了k个元素,那么从map中移除最旧的元素(即nums[i - k])的桶ID和值。这是为了保持map中只存储最近的k个元素的桶ID和值。
  4. 如果遍历完整个数组都没有找到满足条件的两个元素,则返回false

getID方法用于计算给定元素x的桶ID。根据x的正负性,使用不同的计算方法,以确保相同的桶ID范围。

  • 7
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

下水道程序员

你的鼓励将是我奋斗的最大动力。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值