[LeetCode]剑指 Offer 40. 最小的k个数

发布于:2022-12-31 ⋅ 阅读:(352) ⋅ 点赞:(0)

输入整数数组 arr ,找出其中最小的 k 个数。例如,输入 4、5、1、6、2、7、3、8 这 8 个数字,则最小的 4 个数字是 1、2、3、4。

示例 1:

输入:arr = [3,2,1], k = 2
输出:[1,2] 或者 [2,1]

示例 2:

输入:arr = [0,1,2,1], k = 1
输出:[0]

限制:

  • 0 <= k <= arr.length <= 10000
  • 0 <= arr[i] <= 10000

来源:

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/zui-xiao-de-kge-shu-lcof

题解一:

排序:排序后返回数组的前 k 个数即可

时间复杂度和空间复杂度未定,取决于所使用的排序算法

	/**
     * 剑指 Offer 40. 最小的k个数     
     */
    public int[] getLeastNumbers(int[] arr, int k) {
        Arrays.sort(arr);
        return Arrays.copyOf(arr, k);
    }

题解二:

快排:利用快速排序算法(升序)基准数左边的数均小于基准数的特点,对原数组进行快排,若在某一趟快排过程中基准数左边(含基准数)的元素个数等于 k 则直接返回子数组即可

时间复杂度 O(Nlog2N):快排平均时间复杂度为 NlogN
空间复杂度 O(N):快排递归深度平均为 O(log2N),最差为 O(N)

在这里插入图片描述

	/**
     * 剑指 Offer 40. 最小的k个数
     */
    public int[] getLeastNumbers(int[] arr, int k) {
        return k >= arr.length ? arr : quickSort(arr, 0, arr.length - 1, k);
    }

    public static int[] quickSort(int[] arr, int start, int end, int k) {
        int i = start;
        int j = end;
        // 每轮快排选取最左边的元素作为基准数
        int base = arr[start];

        while (i < j) {
            // 从右往左寻找不大于基准数的元素
            while (j > i && arr[j] >= base) {
                j--;
            }
            // 从左往右寻找不小于基准数的元素
            while (i < j && arr[i] <= base) {
                i++;
            }

            // 交换
            int tmp = arr[i];
            arr[i] = arr[j];
            arr[j] = tmp;
        }

        // 移动基准数
        arr[start] = arr[i];
        arr[i] = base;

        // 左序列比基准数小的元素个数大于 k,左序列继续快排
        if (i > k) {
            return quickSort(arr, start, i - 1, k);
        }
        // 左序列比基准数小的元素个数小于 k,右序列快排
        if (i < k) {
            return quickSort(arr, i + 1, end, k);
        }
        return Arrays.copyOf(arr, k);
    }

网站公告

今日签到

点亮在社区的每一天
去签到