LeetCode Maximum Gap

Given an unsorted array, find the maximum difference between the successive elements in its sorted form.

Try to solve it in linear time/space.

Return 0 if the array contains less than 2 elements.

You may assume all elements in the array are non-negative integers and fit in the 32-bit signed integer range.

思路分析:这题要求O(N)的时间和空间复杂度。显然不能使用quick sort,merge sort。 heap sort这类基于比較的排序算法,由于是O(Nlog(N))的时间复杂度。

于是我们考虑使用bukit sort,radix sort,counting sort的思路。

这里给出基于bukit sort的解法。如果num数组中最大值和最小值为max和min。那么我们能够令每个桶的大小为bukitLength = Math.ceil((double) (max - min) / (double) (n-1)),我们定义(max -  min) / bukitLength  + 1个桶。就能够保证存下从min到max这个range内的全部值。

注意事实上我们也能够定义其它的桶大小,比方Math.ceil((double) (max - min) / (double) (n)), 但此时要注意防止出现最大元素的桶index越界的情况,我们能够多定义一个bukit。

定义好桶之后。就能够依据元素大小放入桶中。

注意max gap不可能存在于同一个桶的元素之间。由于同一个桶的元素之间个gap至多仅仅能是bukitLength-1,如果max gap是某两个同一个桶中的元素。那么这些数的range一定比max - min要小。出现矛盾。

所以,对于数组中的随意整数K,能够通过算式loc = (K - min) / bukitLength找出其桶的位置。然后维护每个桶的最大值和最小值。

对于每个非空的桶p,找出下一个非空的桶q,则q.min - p.max可能就是备选答案。

返回这些备选答案中最大的一个就可以。在实现的过程中犯了一个不该犯的错误,没有凝视掉測试输出语句。导致超时。输出语句显然是非常费时的,以后要引以为戒。

AC Code

public class Solution {
    public int maximumGap(int[] num) {
        if(num ==  null || num.length < 2) return 0;
        int n = num.length;
        int max = Integer.MIN_VALUE;
        int min = Integer.MAX_VALUE;
        for(int i = 0; i < n; i++){
            max = Math.max(max, num[i]);
            min = Math.min(min, num[i]);
        }
        int range = max - min;
        int bukitLength = (int)Math.ceil((double) range / (double) (n-1));
        int bukitNum = range / bukitLength + 1;
        //System.out.println("BukitLength and BukitNum " + bukitLength + " " + bukitNum);
        
        ArrayList<Integer> bukitMax = new ArrayList<Integer>();
        ArrayList<Integer> bukitMin = new ArrayList<Integer>();
        
        for(int i = 0; i < bukitNum; i++){
        	bukitMax.add(Integer.MIN_VALUE);
        	bukitMin.add(Integer.MAX_VALUE);
        }
         
        for(int i = 0; i < n; i++){
            int bukitIndex = (num[i] - min) / bukitLength; 
            //if(bukitIndex == n) bukitIndex--; // use n-1 bukits could solve the index problem of the largest number
            //System.out.println("i and bukitIndex: " + i + " " + bukitIndex);
            //Just store the largest and minimum number;
            bukitMax.set(bukitIndex, Math.max(num[i], bukitMax.get(bukitIndex)));
            bukitMin.set(bukitIndex, Math.min(num[i], bukitMin.get(bukitIndex)));
        }

        int beforeMax = min;
        int maxGap = Integer.MIN_VALUE;
        for(int i = 0; i < bukitNum; i++){
        	if(bukitMax.get(i) == Integer.MIN_VALUE || bukitMin.get(i) == Integer.MAX_VALUE){//empty bukit
        		continue;
        	}
        	maxGap = Math.max(maxGap, bukitMin.get(i) - beforeMax);
        	beforeMax = bukitMax.get(i);
        }
        return maxGap;
    }
}



原文地址:https://www.cnblogs.com/wzzkaifa/p/7298416.html