数据结构与算法(Java) 17:桶排序的应用[含对数器]⭐⭐⭐

题目 给定一个数组,求如果排序之后,相邻两数的最大差值,要求时 间复杂度O(N),且要求不能用非基于比较的排序。

思路 应用桶排序,但是要基于排序来操作。步骤如下:

(1)遍历数组,找出数组的最大值max和最小值min,若max==min则说明数组中数字相同,返回0;

(2)以min和max为区间端点,均等划分arr.length+1个桶(可以理解为区间);

(3)遍历数组,若当前数字属于第i个桶,则更新并记录第i个桶的当前最大值、最小值,并标记此桶已经有过数值。

(4)相邻数的最大差值必然存在于不同的桶之间。因为有arr.length个数值,而有arr.lrngth+1个桶,所以必然存在空桶。桶内数值之间的差值必然小于隔一个空桶的差值。所以,相邻数的最大差值必然存在于不同的桶之间,即前一个非空桶的最大值与后一个非空桶的最小值之差。

package algorithm.section2;

import java.util.Arrays;

public class MaxGap {
    public static int maxGap(int[] arr){
        if (arr == null || arr.length < 2) return 0;

        int[] maxs = new int[arr.length + 1];
        int[] mins = new int[arr.length + 1];
        boolean[] hasNum = new boolean[arr.length + 1];

        int max = Integer.MIN_VALUE;
        int min = Integer.MAX_VALUE;

        for (int i = 0; i < arr.length; i++){
            max = Math.max(max, arr[i]);
            min = Math.min(min, arr[i]);
        }

        if (max == min) return 0;

//        double gap = (double) ((max - min) / arr.length);

        for (int i = 0; i < arr.length; i++){
            int index = (int) ((arr[i] - min) * arr.length / (max - min));
            maxs[index] = hasNum[index] ? Math.max(maxs[index], arr[i]) : arr[i];
            mins[index] = hasNum[index] ? Math.min(mins[index], arr[i]) : arr[i];
            hasNum[index] = true;
        }

        int res = 0;
        int lastMax = maxs[0];
        for (int i = 1; i <= arr.length; i++){
            if (hasNum[i]) {
                res = Math.max(res, mins[i] - lastMax);
                lastMax = maxs[i];
            }
        }

        return res;
    }

    // for test
    public static int comparator(int[] nums) {
        if (nums == null || nums.length < 2) {
            return 0;
        }
        Arrays.sort(nums);
        int gap = Integer.MIN_VALUE;
        for (int i = 1; i < nums.length; i++) {
            gap = Math.max(nums[i] - nums[i - 1], gap);
        }
        return gap;
    }

    // for test
    public static int[] generateRandomArray(int maxSize, int maxValue) {
        int[] arr = new int[(int) ((maxSize + 1) * Math.random())];
        for (int i = 0; i < arr.length; i++) {
            arr[i] = (int) ((maxValue + 1) * Math.random()) - (int) (maxValue * Math.random());
        }
        return arr;
    }

    // for test
    public static int[] copyArray(int[] arr) {
        if (arr == null) {
            return null;
        }
        int[] res = new int[arr.length];
        for (int i = 0; i < arr.length; i++) {
            res[i] = arr[i];
        }
        return res;
    }

    // for test
    public static void main(String[] args) {
        int testTime = 500000;
        int maxSize = 10;
        int maxValue = 100;
        boolean succeed = true;
        for (int i = 0; i < testTime; i++) {
            int[] arr1 = generateRandomArray(maxSize, maxValue);
            int[] arr2 = copyArray(arr1);
            if (maxGap(arr1) != comparator(arr2)) {
                succeed = false;
                break;
            }
        }
        System.out.println(succeed ? "Nice!" : "Fucking fucked!");
    }
}
发布了149 篇原创文章 · 获赞 36 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/Dorothy_Xue/article/details/105476811