0%

最小的k个数


题目:

题解:

1、快速排序

  • 解题思路:对原数组从小到大排序后取出前 k 个数即可。

  • 复杂度分析:

    • 时间复杂度 O(NlogN) : 库函数、快排等排序算法的平均时间复杂度为 O(NlogN) 。
    • 空间复杂度 O(N) : 快速排序的递归深度最好(平均)为 O(logN) ,最差情况(即输入数组完全倒序)为 O(N)。
  • 代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    // 快速排序
    class Solution2 {
    public int[] getLeastNumbers(int[] arr, int k) {
    quickSort(arr, 0, arr.length - 1);
    return Arrays.copyOf(arr, k);
    }

    private void quickSort(int[] arr, int l, int r) {
    if (l >= r) return;
    int i = l,j = r;
    while (i < j) {
    while (i < j && arr[j] >= arr[l] ) j--;
    while (i < j && arr[i] <= arr[l] ) i++;
    swap(arr, i, j);
    }
    swap(arr,i,l);
    quickSort(arr,l,i-1);
    quickSort(arr,i+1,r);
    }
    private void swap(int[] arr, int i, int j) {
    int tmp = arr[i];
    arr[i] = arr[j];
    arr[j] = tmp;
    }
    }

2、基于快速排序的数组划分

  • 解题思路:题目只要求返回最小的 k 个数,对这 k 个数的顺序并没有要求。因此,只需要将数组划分为 最小的 k 个数 和 其他数字 两部分即可,而快速排序的哨兵划分可完成此目标。

  • 复杂度分析:

    本方法优化时间复杂度的本质是通过判断舍去了不必要的递归(哨兵划分)。

  • 代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    // 快速排序优化版
    class Solution3 {
    public int[] getLeastNumbers(int[] arr, int k) {
    if (k == 0 || arr.length == 0) {
    return new int[0];
    }
    if (k >= arr.length) return arr;
    return quickSort(arr, k-1, 0, arr.length - 1);
    }
    private int[] quickSort(int[] arr, int k, int l, int r) {
    int i = l, j = r;
    while (i < j) {
    while (i < j && arr[j] >= arr[l]) j--;
    while (i < j && arr[i] <= arr[l]) i++;
    swap(arr, i, j);
    }
    swap(arr, i, l);
    if (i > k) return quickSort(arr, k, l, i - 1);
    if (i < k) return quickSort(arr, k, i + 1, r);
    return Arrays.copyOf(arr, k+1);
    }
    private void swap(int[] arr, int i, int j) {
    int tmp = arr[i];
    arr[i] = arr[j];
    arr[j] = tmp;
    }
    }