codeTop100题(8)912. 排序数组

95 阅读1分钟

1. 题目

912. 排序数组

2. 分析

使用快排进行排序

  • 确定左右边界
  • 选中基准值
  • 指针a指向左边界,从左边界开始找到每一个小于基准值的数字与指针a进行替换,同时指针a右移
  • 指针a与基准值替换
  • 左边界到指针a前和指针a后到右边界的两个子数组进行排序

3. 代码

3.1 快排

class Solution {
    public static int[] sortArray(int[] nums) {
        sortArray(nums, 0, nums.length - 1);
        return nums;
    }

    private static void sortArray(int[] nums, int i, int j) {
        if (i >= j) {
            return;
        }
        int pre = i;
        for (int k = i; k < j; k++) {
            if (nums[k] < nums[j]) {
                swap(nums, pre++, k);
            }
        }
        swap(nums, pre , j);
        sortArray(nums, i, pre - 1);
        sortArray(nums, pre + 1, j);
    }


    public static void swap(int[] t, int a, int b) {
        int s = t[a];
        t[a] = t[b];
        t[b] = s;
    }

}

3.2 随机基准值优化

class Solution {
    
    public static int[] sortArray(int[] nums) {
        sortArray(nums, 0, nums.length - 1);
        return nums;
    }

    private static void sortArray(int[] nums, int i, int j) {
        if (i >= j) {
            return;
        }
        random(nums, i, j);
        int pre = i;
        for (int k = i; k < j; k++) {
            if (nums[k] < nums[j]) {
                swap(nums, pre++, k);
            }
        }
        swap(nums, pre , j);
        sortArray(nums, i, pre - 1);
        sortArray(nums, pre + 1, j);
    }

    private static void random(int[] nums, int i, int j) {
        Random random = new Random();
        int t = random.nextInt(j - i) + i;
        swap(nums, t, j);
    }


    public static void swap(int[] t, int a, int b) {
        int s = t[a];
        t[a] = t[b];
        t[b] = s;
    }

}

但是在执行一个全是2的case的时候,复杂度是n^2,超时了

3.3 增加桶排

class Solution {
    
    public static int[] sortArray(int[] nums) {

        sortArray(nums, 0, nums.length - 1);
        return nums;
    }

    private static void sortArray(int[] nums, int i, int j) {
        if (i >= j) {
            return;
        }
        random(nums, i, j);
        int pre = i;
        //记录一下如果相同元素超过50%,使用其他排序算法
        Map<Integer, Integer> map = new HashMap<>();
        int max = Integer.MIN_VALUE;
        int iMin = Integer.MAX_VALUE ;
        int iMax = Integer.MIN_VALUE;
        for (int k = i; k < j; k++) {
            map.put(nums[k], null == map.get(nums[k]) ? 1 : map.get(nums[k]) + 1);
            max = Math.max(max, map.get(nums[k]));
            iMin = Math.min(nums[k], iMin);
            iMax = Math.max(nums[k], iMax);

            if (nums[k] < nums[j]) {
                swap(nums, pre++, k);
            }
        }
        if ((double) max / (double)nums.length > 0.5) {
            bucketSort(nums, iMax, iMin);
            return;
        }
        swap(nums, pre , j);
        sortArray(nums, i, pre - 1);
        sortArray(nums, pre + 1, j);
    }

    private static void bucketSort(int[] nums, int iMax, int iMin) {
        int[] a = new int[iMax - iMin + 1];

        for (int num : nums) {
            a[num - iMin] += 1;
        }
        int t = 0;
        for (int i = 0; i < a.length; i++) {
            for (int j = 0; j < a[i]; j++) {
                nums[t++] = i + iMin;
            }
        }
    }

    private static void random(int[] nums, int i, int j) {
        Random random = new Random();
        int t = random.nextInt(j - i) + i;
        swap(nums, t, j);
    }


    public static void swap(int[] t, int a, int b) {
        int s = t[a];
        t[a] = t[b];
        t[b] = s;
    }


}