算法-无序数组排序后相邻两个元素的最大差值

求一个无序数组排序后,相邻两个元素的最大差值。

如:

{17, 0, 99, 23, 67, 13, 14, 89, 4}

输出:

32       // 77 - 45

思路:

显然先排序,后暴力是可以做出来的,不过,有更好的办法,那就是桶排序。

  • 1,对于n个数,设置n+1个桶
  • 2,计算桶长:(max-min)/n,桶长不一定是整数,只要确保其长度一致
  • 3,每个桶的长度(范围)一致,然后将n个数投入这n+1个桶,其中最小值一定要投入第一个桶,最大值投入最后一个桶。在分桶过程中,无需记录所有数字,只需要把每个桶的最大值和最小值找出来。

n+1个桶,n个数,至少有一个空桶

桶是等长的,所以相邻两个元素的最大差值一定不是同一个桶的两个相邻元素,而是中间隔了一个或多个空桶的两个桶,即大桶的最小值与小桶的最大值之差。

  • 4,找出所有满足隔了空桶的两个桶的差值,最大的即为所求。

桶示意如下:

算法-无序数组排序后相邻两个元素的最大差值_第1张图片
其中桶长:double bucketLen = new Double(max - min)/arr.length;
计算每个数所属桶: int bucketIndex = (int)((num - min)/bucketLen);

数组分桶后的情况如下,最大差值一定是隔了空桶的两个桶的最小值与最大值之差:
算法-无序数组排序后相邻两个元素的最大差值_第2张图片

package leetcode2;

/**
 * 一个数组排序后,相邻两个元素的最大差值
 */
public class MaxSubInSortedArray {

    public static void main(String[] args) {
        int[]arr = new int[] {17, 0, 99, 23, 67, 13, 14, 89, 4};
        findMaxSub(arr);
    }

    private static void findMaxSub(int[] arr) {
        int min=arr[0],max=arr[0];
        for (int i=0;i<arr.length;i++) {
            min = min > arr[i] ? arr[i] : min;
            max = max < arr[i] ? arr[i] : max;
        }

        // 桶最大值
        int[]arrMax = new int[arr.length+1];
        // 桶最小值
        int[]arrMin = new int[arr.length+1];
        // 是否空桶
        boolean[]arrFlag = new boolean[arr.length+1];
        double bucketLen = new Double(max - min)/arr.length;

        // 分桶,找出每个桶的最大值和最小值
        for (int i=0;i<arr.length;i++) {
            int num = arr[i];
            int bucketIndex = (int)((num - min)/bucketLen);

            if (!arrFlag[bucketIndex]) {
                arrMax[bucketIndex] = arrMin[bucketIndex] = num;
            }

            arrMax[bucketIndex]  = arrMax[bucketIndex] < num ? num : arrMax[bucketIndex];
            arrMin[bucketIndex]  = arrMin[bucketIndex] > num ? num : arrMin[bucketIndex];

            // 标识这个桶非空
            arrFlag[bucketIndex] = true;

        }

        int maxSub = 0;
        for (int i = 0; i < arrFlag.length-1; i++) {
            if (!arrFlag[i]) {
                int k = i+1;
                while (k<arrFlag.length && !arrFlag[k]) {
                    k++;
                }

                int tmp = arrMin[k] - arrMax[i-1];
                if (maxSub < tmp) {
                    maxSub = tmp;
                }
                i = k;
            }
        }

        System.out.println(maxSub);


    }

}

你可能感兴趣的:(算法-无序数组排序后相邻两个元素的最大差值)