1. 程式人生 > >164. Maximum Gap

164. Maximum Gap

數值 null 一個 imu 技術排序 數字 -- its ati

一、題目

  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;
    }

164. Maximum Gap