左神算法整理笔记05

非比较排序:桶排序、计数排序、 基数排序

桶排序对应的很多都是困难题哦

  • 非基于比较的排序,与被排序的样本的实际数据状况很有关系,所以实际中并不经常使用
  • 时间复杂度0(N),额外空间复杂度0(N)
  • 稳定的排序

非比较排序引例

例子:对0-60的数组进行排序

  • 遍历数组,进行数组频数统计,然后就可以重构出排序结果。可以看出是不基于比较,而是基于桶(桶就是一个容器,就是一个数出现的频次)
  • 桶排序是一个大概念,上面的是计数排序,是桶排序的一个具体实现

例子:对应leetcode-164
给定一个数组,求如果排序之后,相邻两数的最大差值,要求时间复杂度0(N),且要求不能用非基于比较的排序

  • 桶划分的逻辑:
    有9个数,则划分为10个桶;根据最大值和最小值划分为10个范围;每个数进入对应的范围;
    最大值是99,最小值是0,则划分为下面范围的桶;里面的是每个桶对应的范围
    在这里插入图片描述
  • 因为有N个数,而有N+1个桶;最大数和最小数都在两端的桶;那么中间的桶一定有一个空桶;那么最大的差值就空桶左边桶的最大值和右边桶最小值。
  • 每个桶需要记录的元素:是否有数据、最大值、最小值
public int maximumGap(int[] nums) {
    if (nums == null || nums.length < 2) return 0;
    int max = Integer.MIN_VALUE;
    int min = Integer.MAX_VALUE;
    int len = nums.length;
    for (int i = 0; i < len; i++) {
        max = Math.max(max, nums[i]);
        min = Math.min(min, nums[i]);
    }
    if (max == min) {
        return 0;
    }
    boolean[] hasNum = new boolean[len+1];
    int[] maxs = new int[len+1];
    int[] mins = new int[len+1];
    int bid = 0; //表示桶的位数
    for (int i = 0; i < len; i++) {
        // 确定当前数属于几号桶
        bid = bucket(nums[i], len, min, max);
        mins[bid] = hasNum[bid] ? Math.min(mins[bid], nums[i]) : nums[i];
        maxs[bid] = hasNum[bid] ? Math.max(maxs[bid], nums[i]) : nums[i];
        hasNum[bid] = true;
    }
    int res = 0;
    int lastMax = maxs[0];
    int i = 1;
    for (; i <= len; i++) {
        if (hasNum[i]) {
            res = Math.max(res, mins[i] - lastMax);
            lastMax = maxs[i];
        }
    }
    return res;
}
public int bucket(long num, long len, long min, long max) {
    return (int) ((num - min) * len / (max-min));
}

基数排序

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值