LeetCode 排序算法题型总结

LeetCode 排序算法题型总结

快排

第一次拿起x = nums[left],从右侧找一个比x小的数放到 lfet位置
这时右侧的right空了,再从左侧找个数放到右侧,
以此来推
直到left>=right,我们可以保证 left左侧都是严格小于x的,这时将x放到left的位置(或者这样理解,因为循环最后是nums[j] = nums[i], 所以最后跳出循环后一定是左侧left有空位,所以放到left)
class QuickSort {
    public void quickSort(int[] nums) {
        if (nums == null || nums.length <= 1) return;
        sort(nums, 0, nums.length - 1);
    }

    private void sort(int[] nums, int l, int r) {
        if (l >= r) return; // 递归结束条件

        int pivotIndex = partition(nums, l, r);

        // 对左右两边都进行递归排序
        sort(nums, l, pivotIndex - 1);
        sort(nums, pivotIndex + 1, r);
    }

    private int partition(int[] nums, int l, int r) {
        int pivot = nums[l]; // 选择最左元素作为pivot
        int i = l, j = r;

        while (i < j) {
            while (i < j && nums[j] >= pivot) j--; // 从右找小于pivot的
            nums[i] = nums[j]; // 覆盖到左边

            while (i < j && nums[i] <= pivot) i++; // 从左找大于pivot的
            nums[j] = nums[i]; // 覆盖到右边
        }
        nums[i] = pivot; // 将pivot放到最终位置
        return i;
    }
}

优化-三路划分

  • 注意 swap(nums,i++,lt++);
    • 因为 交换前 nums[it]=p,nums[i]<p,交换后 nums[i]=p这是已知的,所以i++,同时这也保证了 i>=it
class Solution {

    private Random r = new Random();

    public int findKthLargest(int[] nums, int k) {

        int n = nums.length;

        int target = n-1-k+1;

        return helper(nums, 0, n-1, target);

    }

    private int helper(int[] nums, int left, int right ,int target){

        int x = left+ r.nextInt(right-left+1);

        swap(nums, x, left);

        int pivot = nums[left];

        // [left,lt-1]<p, [lt,i]=p , [gt+1,right]>p

        int lt = left, gt = right , i = left;

        while (i<=gt) { // 保证nums[gt+1]>p, 但是gt这个位置还要判断

            if (nums[i]<pivot) {

                swap(nums, i++, lt++);

            }else if (nums[i]>pivot) {

                swap(nums, i, gt--);

            }else{

                i++;

            }

        }

        if (target<=lt-1) {

            return helper(nums, left, lt-1, target);

        }else if (target>=gt+1) {

            return helper(nums, gt+1, right, target);

        }else{

            return nums[lt];

        }

    }

    private void swap(int[] nums, int a,int b){

        int temp = nums[a];

        nums[a] = nums[b];

        nums[b] = temp;

    }

}