zoukankan      html  css  js  c++  java
  • 164. Maximum Gap

    一、题目

      1、审题

      

      2、分析

        给出一个无序的整形数组,求其有序时相邻元素的最大差值为多大。

    二、解答

      1、思路:

        方法一、

          桶排序。

          ①、首先找出数组中最大元素、最小元素: max 、min;

          ②、去除 max、min 时数组剩下 N - 2 个元素,取 N - 1 个桶进行存放,则一个桶内存放元素范围为: ceiling[(max - min ) / (N - 1)] ;且第 k 个桶存放的数值大小范围为 [min+ (k-1)gap, min+ k*gap);

          ③、可知至少有一个桶为空着的,所以相邻元素的最大差值必定在不同的桶之间,也即在前一个有效桶(非空)的最大值与后一个有效桶(非空)的最小值的差。

        public int maximumGap2(int[] nums) {
            
            if(nums == null || nums.length < 2)
                return 0;
            
            int len = nums.length;
            int maxVal = Integer.MIN_VALUE;
            int minVal = Integer.MAX_VALUE;
            
            for (int i = 0; i < len; i++) {
                maxVal = Math.max(maxVal, nums[i]);
                minVal = Math.min(minVal, nums[i]);
            }
            
            // 取 len - 1 个桶时(去除 maxVal、minVal 后剩下 len - 2个数,必有一个空桶), 求解桶间最小的差值,向上取整
            int gap = (int) Math.ceil((double)(maxVal - minVal)/(len - 1));
            int[] maxBuk = new int[len - 1];
            int[] minBuk = new int[len - 1];
            
            Arrays.fill(maxBuk, Integer.MIN_VALUE);
            Arrays.fill(minBuk, Integer.MAX_VALUE);
            // 桶映射
            for(int val: nums) {
                if(val == minVal || val == maxVal)
                    continue;
                int idx = (val - minVal) / gap;
                maxBuk[idx] = Math.max(maxBuk[idx], val);
                minBuk[idx] = Math.min(minBuk[idx], val);
            }
            
            //求解最大gap,最大差值位于后桶的min-前桶的max
            int maxGap = Integer.MIN_VALUE;
            int pre = minVal;
            for (int i = 0; i < len - 1; i++) {
                
                if(maxBuk[i] == Integer.MIN_VALUE && minBuk[i] == Integer.MAX_VALUE)
                    continue;
                maxGap = Math.max(maxGap, minBuk[i] - pre);
                pre = maxBuk[i];
                
            }
            maxGap = Math.max(maxGap, maxVal - pre);
            return maxGap;
        }

      方法二、

        基数排序

        动画演示:https://www.cs.usfca.edu/~galles/visualization/RadixSort.html

        ①、找出数组最大值,用于控制循环;

        ②、运用技术排序,从最低位到最高位进行排序;

        ③、 (nums[i] / exp) % 10 用于获取数字排序的数值, 且数字本身就是访问 count 数组的索引 ;

          count 数组存储访问 AUX 的索引,根据 Aux 当前的顺序存储排序后的数字。

        
        public int maximumGap3(int[] nums) {
            
            if(nums == null || nums.length < 2)
                return 0;
            
            int max = nums[0];
            for (int i = 1; i < nums.length; i++) 
                max = Math.max(max, nums[i]);
            
            int exp = 1;    // 1, 10, 100, 1000
            int R = 10;
            
            int[] aux = new int[nums.length];
            
            while(max / exp > 0) {    // Go through all digits from LSB to MSB
                int[] count = new int[R];
                
                for (int i = 0; i < nums.length; i++) 
                    count[(nums[i] / exp) % 10]++;
                
                for (int i = 1; i < count.length; i++) 
                    count[i] += count[i - 1];
                
                for (int i = nums.length - 1; i >= 0; i--) 
                    aux[--count[(nums[i] / exp) % 10]] = nums[i];
                
                for (int i = 0; i < nums.length; i++) 
                    nums[i] = aux[i];
                
                exp *= 10;
            }
            
            max = 0;
            for (int i = 1; i < aux.length; i++) 
                max = Math.max(max, aux[i] - aux[i - 1]);
                
            return max;
        }
  • 相关阅读:
    JS定时器做物体运动
    JS做动态表格
    JS如何做2048(详细)
    改变 C/C++ 控制台程序的输出颜色和样式
    The Game Of Life – 数据结构与算法的敲门砖
    适用于 macOS 下 2K 显示器开启 HiDPI 的简便解决方案
    「踩坑记」Android API 判断权限申请结果的闪退问题
    Hello World!
    js 放大镜效果
    js 随机验证码生成及校验
  • 原文地址:https://www.cnblogs.com/skillking/p/9789980.html
Copyright © 2011-2022 走看看