LeetCode——面试题 17.14. 最小K个数(Java)

题目描述

题干:
设计一个算法,找出数组中最小的k个数。以任意顺序返回这k个数均可。

示例:
输入: arr = [1,3,5,7,2,4,6,8], k = 4
输出: [1,2,3,4]

题解思路

返回数组中的前k个,首先想都不要想直接就是排序返回前k个直接解决

不过既然是面试题,我们就多想几个办法吧,只要是返回最大或者最小的元素

我们可以借助堆结构来实现,这里给出最小堆的写法,官方题解给出的最大堆的显得有些啰嗦

如果还要优化,当然那就是从排序算法上继续做文章,自己写快排算法进行排序会更快

正确代码

    // 排序
    public int[] smallestK(int[] arr, int k) {
        int[] ans = new int[k];
        Arrays.sort(arr);
        for (int i = 0; i < k; i++) {
            ans[i] = arr[i];
        }
        return ans;
    }

    // 最小堆
    public int[] smallestK01(int[] arr, int k) {
        int[] vec = new int[k];

        if (k == 0) {
            return vec;
        }

        PriorityQueue<Integer> queue = new PriorityQueue<>(new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o1 - o2;
            }
        });

        for (int i : arr) {
            queue.offer(i);
        }

        for (int i = 0; i < vec.length; i++) {
            vec[i] = queue.poll();
        }

        return vec;
    }

    // 大顶堆
    public int[] smallestK2(int[] arr, int k) {
        int[] vec = new int[k];
        if (k == 0) { // 排除 0 的情况
            return vec;
        }
        PriorityQueue<Integer> queue = new PriorityQueue<Integer>(new Comparator<Integer>() {
            public int compare(Integer num1, Integer num2) {
                return num2 - num1;
            }
        });
        for (int i = 0; i < k; ++i) {
            queue.offer(arr[i]);
        }
        for (int i = k; i < arr.length; ++i) {
            if (queue.peek() > arr[i]) {
                queue.poll();
                queue.offer(arr[i]);
            }
        }
        for (int i = 0; i < k; ++i) {
            vec[i] = queue.poll();
        }
        return vec;
    }

总结

这里要说一说Arrays中的sort方法,它内部采用的排序算法根据长度而定

如果排序元素在47之下则用插入排序,在47到268之间用快速排序

再多的话就用归并排序的方法,但是具体细节还和传统的这些算法不同,增加了细节

如果文章存在问题或者有更好的题解,欢迎再评论区斧正和评论,各自努力,你我最高处见
posted @ 2021-09-03 14:09  21岁还不是架构师  阅读(54)  评论(0编辑  收藏  举报