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



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值