二叉樹-快排-leetcode912

給你一個整數數組 nums,請你將該數組升序排列。

示例 1:

輸入:nums = [5,2,3,1]
輸出:[1,2,3,5]
示例 2:

輸入:nums = [5,1,1,2,0,0]
輸出:[0,0,1,1,2,5]
提示:

1 <= nums.length <= 5 * 104
-5 * 104 <= nums[i] <= 5 * 104

思路:快排,或者叫前序二叉樹,排序後端結果是一個二叉搜索樹


//leetcode submit region begin(Prohibit modification and deletion)
class Solution {
    public int[] sortArray(int[] nums) {
        sort(nums);
        return nums;
    }

    public static void sort(int[] nums) {
        // 爲了避免出現耗時的極端情況,先隨機打亂
        //shuffle(nums);
        // 排序整個數組(原地修改)
        sort(nums, 0, nums.length - 1);
    }

    private static void sort(int[] nums, int lo, int hi) {
        if (lo >= hi) {
            return;
        }
        // 對 nums[lo..hi] 進行切分
        // 使得 nums[lo..p-1] <= nums[p] < nums[p+1..hi]
        int p = partition(nums, lo, hi);

        sort(nums, lo, p - 1);
        sort(nums, p + 1, hi);
    }

    // 對 nums[lo..hi] 進行切分
    private static int partition(int[] nums, int lo, int hi) {
        int pivot = nums[lo];
        // 關於區間的邊界控制需格外小心,稍有不慎就會出錯
        // 我這裏把 i, j 定義爲開區間,同時定義:
        // [lo, i) <= pivot;(j, hi] > pivot
        // 之後都要正確維護這個邊界區間的定義
        int i = lo + 1, j = hi;
        // 當 i > j 時結束循環,以保證區間 [lo, hi] 都被覆蓋
        while (i <= j) {
            while (i < hi && nums[i] <= pivot) {
                i++;
                // 此 while 結束時恰好 nums[i] > pivot
            }
            while (j > lo && nums[j] > pivot) {
                j--;
                // 此 while 結束時恰好 nums[j] <= pivot
            }
            // 此時 [lo, i) <= pivot && (j, hi] > pivot

            if (i >= j) {
                break;
            }
            swap(nums, i, j);
        }
        // 將 pivot 放到合適的位置,即 pivot 左邊元素較小,右邊元素較大
        System.out.println("lo"+lo);
        System.out.println("j"+j);
        swap(nums, lo, j);
        return j;
    }

    // 洗牌算法,將輸入的數組隨機打亂
    private static void shuffle(int[] nums) {
        Random rand = new Random();
        int n = nums.length;
        for (int i = 0 ; i < n; i++) {
            // 生成 [i, n - 1] 的隨機數
            int r = i + rand.nextInt(n - i);
            swap(nums, i, r);
        }
    }

    // 原地交換數組中的兩個元素
    private static void swap(int[] nums, int i, int j) {
        int temp = nums[i];
        nums[i] = nums[j];
        nums[j] = temp;
    }
}
//leetcode submit region end(Prohibit modification and deletion)


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章