二分与排序中等1 种解法

#912排序数组

将整数数组按升序原地排序并返回;这里整理旧源码中的随机化快速排序。

#数组#排序#快速排序#分治

解题主线

01

分区把枢轴放到最终位置,并保证左侧不大于枢轴、右侧不小于枢轴,再递归处理两侧。

02

随机选择枢轴可减少有序输入稳定触发极端分区的风险。

03

挖坑分区交替从右找小值、从左找大值,指针相遇处就是枢轴最终位置。

解法 1随机枢轴挖坑快速排序

把随机枢轴交换到左端,交替搬运右侧较小值和左侧较大值,枢轴归位后递归排序两侧。

时间复杂度

期望 O(n log n),最坏 O(n²)

空间复杂度

期望 O(log n),最坏 O(n),来自递归栈

912. 排序数组 · 随机枢轴挖坑快速排序
import java.util.concurrent.ThreadLocalRandom;

final class Solution {
    public int[] sortArray(int[] nums) {
        if (nums == null) throw new IllegalArgumentException("nums must not be null");
        quickSort(nums, 0, nums.length - 1);
        return nums;
    }

    private void quickSort(int[] nums, int left, int right) {
        if (left >= right) return;
        int pivotIndex = partition(nums, left, right);
        quickSort(nums, left, pivotIndex - 1);
        quickSort(nums, pivotIndex + 1, right);
    }

    private int partition(int[] nums, int left, int right) {
        int randomIndex = ThreadLocalRandom.current().nextInt(left, right + 1);
        swap(nums, left, randomIndex);
        int pivot = nums[left];
        int low = left;
        int high = right;

        while (low < high) {
            while (low < high && nums[high] >= pivot) high--;
            nums[low] = nums[high];
            while (low < high && nums[low] <= pivot) low++;
            nums[high] = nums[low];
        }
        nums[low] = pivot;
        return low;
    }

    private void swap(int[] nums, int first, int second) {
        int temporary = nums[first];
        nums[first] = nums[second];
        nums[second] = temporary;
    }
}

把随机枢轴交换到左端,交替搬运右侧较小值和左侧较大值,枢轴归位后递归排序两侧。

  • 旧文件两个 partition 都服务于同一快速排序策略,未作为重复解法拆分;保留并启用了修正后的挖坑版本。

边界与易错点

  • 旧 partition1 的第二段扫描错误地判断 nums[right] 而不是 nums[left],且 sortArray 从未调用它;整理后修正条件并让快速排序实际使用该分区。
  • 分区内移动指针时必须始终检查 left < right,避免越界或死循环。
  • 快速排序最坏时间 O(n²)、最坏递归深度 O(n);随机化改善期望表现但不消除最坏情况。
整理来源

由旧仓库源码复核、去重并整理;展示代码已按 Java 21 语义修正明显问题。

leetcode/src/main/java/medium/Q912_sort.java