美文网首页
算法笔记之桶排序

算法笔记之桶排序

作者: 简单一点点 | 来源:发表于2020-12-04 08:45 被阅读0次

桶排序的思想很简单,将区间划分为n个等长的子区间。然后,将各个元素按照自己所属的区间放入相应的桶中,只需要将每个桶的元素排好序,依次输出各个桶内的元素,就得到了有序的元素序列。

桶排序的两个核心问题:

  • 每个桶的长度是多少?换句话说,每个桶放置元素的范围是什么?
  • 一共要准备多少个桶?

使用桶排序的场景不是很多,看一个例题。

LeetCode 164. 最大间距

题目描述:给定一个无序的数组,找出数组在排序之后,相邻元素之间最大的差值。如果数组元素个数小于 2,则返回 0。

你可以假设数组中所有元素都是非负整数,且数值在 32 位有符号整数范围内。请尝试在线性时间复杂度和空间复杂度的条件下解决此问题。

解题思路:设长度为 N 的数组中最大值为 \textit{max,min},则不难发现相邻数字的最大间距不会小于 \lceil (\textit{max}-\textit{min}) / (N-1) \rceil

因此,我们可以以此长度为桶的长度(注意不能小于1),将各个数字放到桶中,这里不同的是我们不需要对桶内的数字进行详细排序,只需要找到最大值和最小值。由于桶内相邻数字之间的间距肯定不是最大间距,所以我们只需要求出不同桶之间相邻数字的间距即可。

Java代码:

class Solution {
    // 线性时间复杂度和空间复杂度 不能用Arrays.sort
    public int maximumGap(int[] nums) {
        if (nums.length < 2) return 0;
        int len = nums.length;

        // 找出最大值和最小值 为了方便后面确定桶的数量
        int max = -1, min = Integer.MAX_VALUE;
        for (int i  = 0; i < len; i++) {
            max = Math.max(nums[i], max);
            min = Math.min(nums[i], min);
        }

        // 排除nums全部为一样的数字,nums = [1,1,1,1,1,1];
        if (max - min == 0) return 0;
        // 用于存放每个桶的最大值
        int[] bucketMin = new int[len - 1];
        // 用于存放每个桶的最小值
        int[] bucketMax = new int[len - 1];
        Arrays.fill(bucketMax, -1);
        Arrays.fill(bucketMin, Integer.MAX_VALUE);

        // 确定桶的间距
        int interval = (int)Math.ceil((double)(max - min) / (len - 1));
        for (int i = 0; i < len; i++) {
            // 找到每一个值所对应桶的索引
            int index = (nums[i] - min) / interval;
            if (nums[i] == min || nums[i] == max) continue;
            // 更新每个桶的数据
            bucketMax[index] = Math.max(bucketMax[index], nums[i]);
            bucketMin[index] = Math.min(bucketMin[index], nums[i]);
        }

        // maxGap 表示桶之间最大的差距
        int maxGap = 0;
        // preMax 表示前一个桶的最大值
        int preMax = min;
        for (int i = 0; i < len - 1; i++) {
            // 表示某一个桶为空
            // 但凡某一个桶不为空,都会在前面的数据中更新掉bucketMax的值
            if (bucketMax[i] == -1) continue;
            maxGap = Math.max(bucketMin[i] - preMax, maxGap);
            preMax = bucketMax[i];
        }
        // [1,10000000]
        maxGap = Math.max(maxGap, max - preMax);
        return maxGap;
    }
}

相关文章

  • 算法笔记之桶排序

    桶排序的思想很简单,将区间划分为n个等长的子区间。然后,将各个元素按照自己所属的区间放入相应的桶中,只需要将每个桶...

  • 线性排序

    桶排序、计数排序、基数排序 一、线性排序算法介绍 1.线性排序算法包括桶排序、计数排序、基数排序。2.线性排序算法...

  • 浅谈排序算法

    排序算法有很多种,今天先谈谈一些简单的排序算法。包括桶排序、冒泡排序和快速排序算法。后期总结各种排序算法。 桶排序...

  • 七大排序算法之冒泡排序

    七大排序算法之冒泡排序 @(算法笔记)[排序算法, 冒泡排序, C++实现] 冒泡排序介绍 冒泡排序是七大排序算法...

  • 七大排序算法之快速排序

    七大排序算法之快速排序 @(算法笔记)[排序算法, 快速排序, C++实现] [TOC] 快速排序的介绍: 快速排...

  • 排序算法(十一)桶排序

    排序算法(十一)桶排序   桶排序(Bucket sort)是计数排序改进版,同样属于非比较排序,该算法的基本思想...

  • (转)排序算法

    排序算法点这里 数据结构与算法——计数排序、桶排序、基数排序

  • 排序算法三(桶,计数,基数)

    桶排序,计数排序,基数排序算法的时间复杂度都是线性的,所以把这类排序算法叫作线性排序。 桶排序 概念:将要排序的数...

  • 排序算法之桶排序

    介绍 桶排序是一个排序算法,工作的原理是将数组中的元素分到有限数量的桶里。每个桶再个别排序(有可能再使用别的排序算...

  • 排序:桶排序、冒泡排序、快速排序

    拜读《啊哈算法》后的内容笔记。 简易的桶排序 [真正的桶排序并非如此简单]原理:将数组中的某个数,例如6,则将结果...

网友评论

      本文标题:算法笔记之桶排序

      本文链接:https://www.haomeiwen.com/subject/sojbwktx.html