相邻两数最大差值

2 篇文章 0 订阅

有一个整形数组A,请设计一个复杂度为O(n)的算法,算出排序后相邻两数的最大差值。
给定一个int数组A和A的大小n,请返回最大的差值。保证数组元素多于1个。

public class 相邻两数最大差值 {
    public int maxGap(int[] A, int n) {
        int gapValue[] = new int[n - 1];
        int k = 0;
        Arrays.sort(A);
        for (int i = 0; i < n - 1 && k < n - 1; i++) {
            gapValue[k++] = A[i + 1] - A[i];
        }

        int max=Integer.MIN_VALUE;
        for(int i=0;i<n-1;i++){
            if (gapValue[i]>max) {
                max=gapValue[i];
            }
        }

        return max;
    }

/*
 * 另一种方法:
 *      最优解时间复杂度O(N),额外空间复杂度O(N)
 *      思想来自桶排序(和数组范围无关)
 *      1、遍历数组,找到数组的最大值和最小值
 *      2、在最大值和最小值范围内分成n个等量的空间,每个区间分别对应一个桶
 *      3、遍历数组的每一个值,除了把最大值装在第n+1个桶外,把每一个值放在对应的区间里
 *      4、因为有n个数,n+1个桶,所以中间一定有空桶,因为同一个桶内差值不大,所以只需要考虑桶前面的一个数,和桶后面的数之间的差值
 */
    public static int MaxGap(int [] A,int n){
        if (A==null || A.length<2) {
            return 0;
        }

        int min=Integer.MAX_VALUE;
        int max=Integer.MIN_VALUE;
        for(int i=0;i<n;i++){
            max=Math.max(max, A[i]);
            min=Math.min(min, A[i]);
        }
        if (min==max) {
            return 0;
        }

        int len=A.length;
        int mins[]=new int[len+1];//存放每个桶中的最小值,存入元素时更新此
        int maxs[]=new int [len+1];
        boolean hasNum[] = new boolean[len+1];//用来标记是否为空桶

        //向桶中放入元素
        int bid=0;
        for(int i=0;i<len;i++){
            bid=bucket(A[i], len, min, max);//第几只桶
            mins[bid]=hasNum[bid]?Math.min(mins[bid], A[i]):A[i];//如果hasNum为true,mins[bid]就等于该数与上一个该桶中的最小数比较较小的数
            maxs[bid]=hasNum[bid]?Math.max(maxs[bid], A[i]):A[i];
            hasNum[bid]=true;
        }

        //放好元素后,开始计算最大差值
        int gap=0;
        int preMax;//记录前一个桶中的最大值
        int nextMin;//记录后一个桶中的最小值
        int i=0;
        while(i<len+1){
            //寻找第一个空桶
            while(i<len+1 && hasNum[i]){
                i++;
            }

            if (i>=len+1) {
                break;
            }

            preMax=maxs[--i];
            i++;

            //继续循环,找下一个非空的桶(将空桶遍历完)
            while(i<len+1 && !hasNum[i]){
                i++;
            }
            //跳出循环后就是非空的桶
            nextMin=mins[i];

            gap=gap>(nextMin-preMax)?gap:(nextMin-preMax);
        }


        return gap;
    }


    //计算元素改放在第几桶
    public static int bucket(long num,long len, long min, long max){

        return (int) ((num-min)*len/(max-min));//len为等量区间的数目,即桶的的数目(该过程一共需要len+1只桶)
    }

    public static void main(String[] args) {
        int A[]={2,1,3,4,7,8,9};
        int gap=MaxGap(A, A.length);
        System.out.println(gap);
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值