【leetcode-每日一题】无序数组最大相邻差

解法一:利用计数排序思想

  1. 利用计数排序的思想,先求出原数组的最大值max与最小值min
    的区间长度d(d=max-min+1),以及偏移量offset=min。
  2. 创建一个长度为d的新数组Array。
  3. 遍历原数组,每遍历一个元素,就把新数组Array对应下标的值
    +1。例如原数组元素的值为n,则将Array[n-min]的值加1。遍历结束
    后,Array的一部分元素值变成了1或更高的数值,一部分元素值仍然是
    0。
  4. 遍历新数组Array,统计出Array中最大连续出现0值的次数+1,
    即为相邻元素最大差值。

时间复杂度不稳定在 O(n)

如果原数组只有3个元素:1、2、1 000 000,那就要创建长度是1 000 000的数组

代码如下

/**
     * 计数排序
     *
     * @param a 未排序数组
     * @return 最大相邻差
     */
    public static int getMaxSortedDistance(int[] a) {

        int min = a[0];
        int max = a[0];

        //1.获取最小值,最大值
        for (int item : a) {
            if (item >= max) {
                max = item;
            }
            if (item <= min) {
                min = item;
            }
        }

        //2.计数排序思想
        int distance = max - min + 1;
        //偏移量
        int offset = min;
        //创建一个distance长度的数组,存放 a 数组
        int[] array = new int[distance];
        for (int value : a) {
            //原数组元素的值为n,则将Array[n-min]的值加1
            array[value - min]++;
        }

        // 3.遍历新数组,计算最大相邻差
        //统计空值数量
        int count = 0;
        //最大连续数
        int maxCount = 0;

        //连续的起始位置
        int startIndex = 0;
        //结束的开始位置
        int endIndex = 0;
        for (int i = 0; i < array.length; i++) {
            if (array[i] == 0) {
                if (count == 0) {
                    //记录连续为0的前一个位置
                    startIndex = i - 1;
                }
                //统计空值,判断0最多连续出现的次数
                count++;
            } else {
                count = 0;
            }
            if (count > maxCount) {
                maxCount = count;
                //记录连续为0的结束位置的最后一个位置
                endIndex = i + 1;
            }

        }
        //4.返回最大相邻差
        return endIndex - startIndex;
    }

解法二:利用桶排序思想

  1. 利用桶排序的思想,根据原数组的长度n,创建出n个桶,每一个
    桶代表一个区间范围。其中第1个桶从原数组的最小值min开始,区间跨
    度是(max-min)/(n-1)。
  2. 遍历原数组,把原数组每一个元素插入到对应的桶中,记录每一
    个桶的最大和最小值。
  3. 遍历所有的桶,统计出每一个桶的最大值,和这个桶右侧非空桶
    的最小值的差,数值最大的差即为原数组排序后的相邻最大差值。

时间复杂度稳定在 O(n)
代码如下

  /**
     * 桶排序实现相邻两位最大差值
     *
     * @param a 未排序数组
     * @return  最大相邻差
     */
    public static int getgetMaxSortedDistanceByBucket(int[] a) {
        int min = a[0];
        int max = a[0];

        //1.获取最小值,最大值
        for (int value : a) {
            if (value >= max) {
                max = value;
            }
            if (value <= min) {
                min = value;
            }
        }
        int offset = max - min;
        //如果max=min 说明所有元素都相等
        if (offset == 0) {
            return 0;
        }

        //2.初始化捅
        int bucketNum = a.length;
        Bucket[] buckets = new Bucket[bucketNum];
        for (int i = 0; i < bucketNum; i++) {
            buckets[i] = new Bucket();
        }

        //3.遍历原始数组,确定每个桶的最大最小值
        for (int value : a) {
            //确定数组元素所属的桶下标
            int index = (value - min) * (bucketNum - 1) / offset;
            if (buckets[index].min == null || buckets[index].min > value) {
                buckets[index].min = value;
            }
            if (buckets[index].max == null || buckets[index].max < value) {
                buckets[index].max = value;
            }
        }

        //4.遍历桶,找到最大差值
        int leftMax = buckets[0].max;
        int maxDistance = 0;
        for (int i = 1; i < buckets.length; i++) {
            if (buckets[i].min == null) {
                continue;
            }
            if (buckets[i].min - leftMax > maxDistance) {
                maxDistance = buckets[i].min - leftMax;
            }
            leftMax=buckets[i].max;
        }
        return maxDistance;
    }

   

定义Bucket类

 static class Bucket {
        private Integer min;
        private Integer max;
    }
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值