剑指offer 29.最小的K个数(优先队列解决法)

时间限制:1秒 空间限制:32768K 本题知识点: 数组

题目描述
输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,。

思路:
我考虑用最大堆来实现(java自带默认最大堆)可以全部入堆,再出k个元素,即可,但这样会浪费空间,就不符合最小堆动态排序这种特点

import java.util.ArrayList;
import java.util.PriorityQueue;
public class Solution {
    public ArrayList<Integer> GetLeastNumbers_Solution(int [] input, int k) {
         ArrayList<Integer> res = new ArrayList();
        if(k > input.length) {
            return res;
        }
        PriorityQueue<Integer> pq = new PriorityQueue<>();
        for (int i = 0; i < input.length; i++) {
            pq.add(input[i]);
        }
        for (int i = 0; i < k; i++) {
            Integer remove = pq.remove();
            res.add(remove);
        }
        return res;
    }
}

所用时间和空间:

第二种方法是,先入堆k个数(这次需要最大堆,因为要取出堆顶最大的和接下来的数进行比较),然后后面的数依次与堆顶元素比较,如果比堆顶小,就把堆顶元素给移除,把小的元素放进去就好,最后依次取出堆顶放入list集合返回即可,what?这是最大堆,返回的不是从大到小的顺序吗?错!本题没有要求返回的数据是从小到大排好序的,只是要求返回最小的k个数即可.这种方法节省了空间,保证空间的稳定,但是牺牲的是一部分时间.

import java.util.ArrayList;
import java.util.PriorityQueue;
public class Solution {
    public ArrayList<Integer> GetLeastNumbers_Solution(int [] input, int k) {
        ArrayList<Integer> res = new ArrayList();
        if(k > input.length || k == 0) {
            return res;
        }
        PriorityQueue<Integer> pq = new PriorityQueue<>(
                (a,b) -> b - a // 默认就是它,可以不要
        );
        for (int i = 0; i < input.length; i++) {
            if(pq.size() < k) {
                pq.add(input[i]);
                System.out.println(pq.peek());
            } else {
                if (input[i] < pq.peek()) {
                    pq.poll();
                    pq.add(input[i]);
                }
            }
        }
        while (!pq.isEmpty()) {
            Integer remove = pq.remove();
            res.add(remove);
        }
        return res;
    }
}

内存和耗时:

什么鬼,内存和时间更长了?应该是数据太少了,数据多了,就体现出了这样的好处!空间会大大节省.

全部评论

相关推荐

我即大橘:耐泡王
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务