• 每一轮就是这轮的基准数(pivot)归位,直到所有数归位。

  • partition是返回一个基准值(pivot)的index, index左边都 < arr[index], 右边都 > arr[index]

  • 步骤:

    • 定基准 find pivot partition
    • 划分区 divide and conquer, partition by pivot
    • 递归调用
  • optimization

    • 对于很小且部分有序的数组 插排优于快排。所以 分割到某处时 用插排。
    • pivot的选择。最理想的pivot是等分左右。
      • 三位取中 or low&high 中random
      • 若选取的为固定第一/最后 则当输入为有序时(正序/倒序)时 均沦为O(n^2)
// test case: 6,1,2,7,9,3,4,5,10,8
public void quickSort(int[] array) {
    recQuickSort1(array, 0, array.length - 1);
    recQuickSort2(array, 0, array.length - 1);
}

////// similar to preorder traversal!!!
private void recQuickSort1(int[] array, int left, int right) {
    // 确保至少有两个数
    if (left >= right) {
        return;
    }

    // 基准归位 并 切分
    int partition = partition(array, left, partition - 1);

    recQuickSort(array, left, partition - 1);
    recQuickSort(array, partition + 1, right);
}

private int partition(int[] array,int left, int right) {
    int i = left + 1;
    int j = right;
    int pivot = array[left];

    while (i <= j) {   // while(true)??
        while (i <= j && array[i] < pivot) i++;
        while (i <= j && array[j] >= pivot) j--;

        if (i > j) break;
        swap(i, j, array);
    }
    swap(j, left, array);
    return j;
}

////////////////
private void reQuickSort2(int[] array, int left, int right) {
    if (left >= right) return;
    int i = left + 1;
    int j = right;
    int pivot = array[left];

    while (i <= j) {
        while (i <= j && array[i] < pivot) i++;
        while (i <= j && array[j] >= pivot) j--;

        if (i > j) break;
        swap(i, j, array);        
    }
    swap(j, left, array);

    reQuickSort2(array, left, j - 1);     
    reQuickSort2(array, j + 1, right);    // or i? yes both work
}
public class Solution {
    /**
     * @param A an integer array
     * @return void
     */
    public void sortIntegers2(int[] A) {
        quickSort(A, 0, A.length - 1);
    }

    private void quickSort(int[] A, int start, int end) {
        if (start >= end) {
            return;
        }

        int left = start, right = end;
        // key point 1: pivot is the value, not the index
        int pivot = A[(start + end) / 2];

        // key point 2: every time you compare left & right, it should be 
        // left <= right not left < right
        while (left <= right) {
            // key point 3: A[left] < pivot not A[left] <= pivot
            while (left <= right && A[left] < pivot) {
                left++;
            }
            // key point 3: A[right] > pivot not A[right] >= pivot
            while (left <= right && A[right] > pivot) {
                right--;
            }
            if (left <= right) {
                int temp = A[left];
                A[left] = A[right];
                A[right] = temp;

                left++;
                right--;
            }
        }

        quickSort(A, start, right);
        quickSort(A, left, end);
    }
}

find median

public static int findMedian(int[] nums) {
    int median = partition(tem, 0, nums.length-1, nums.length/2);
    return median;
}
public static int partition(int[] nums, int l, int r, int rank) {
        int left = l, right = r;
        int now = nums[left];
        while (left < right) {
            while (left < right && nums[right] >= now) {
                right--;
            }
            nums[left] = nums[right];
            while (left < right && nums[left] <= now) {
                left++;
            }
            nums[right] = nums[left];
        }
        if (left - l == rank) {
            return now;
        } else if (left - l < rank) {
            return partition(nums, left + 1, r, rank - (left - l + 1));
        } else {
            return partition(nums, l, right - 1, rank);
        }
     }

find kth largest / smallest

  • heap: O(nlogk)
  • partition: O(n)

wiggle sort ii

partition template

    public int partition(int[] nums, int l, int r) {
        // 初始化左右指针和pivot
        int left = l, right = r;
        int pivot = nums[left];

        // 进行partition
        while (left < right) {
            while (left < right && nums[right] >= pivot) {
                right--;
            }
            nums[left] = nums[right];
            while (left < right && nums[left] <= pivot) {
                left++;
            }
            nums[right] = nums[left];
        }

        // 返还pivot点到数组里面
        nums[left] = pivot;
        return left;         
    }

results matching ""

    No results matching ""