使用PriorityQueue来实现最大堆

题目:最小的k个数 

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

 

主要思路:使用最大堆,保存目前已知的最小的k个数,堆顶是k个数中最大的元素。遍历数组,若堆中元素个数小于k,则直接添加到当前数字到堆中;若当前数字小于堆顶元素(即堆中最大元素),说明堆顶元素不可能是最小的k个数之一,因此用当前数字替换掉堆顶元素,然后保持堆有序(即最大元素在堆顶);若当前数字大于堆顶元素,说明当前数字不可能是最小的k个数之一,跳过该数字。

Java最大堆API:可使用优先队列来实现最大堆。需要设置比较器为逆序:

 Queue<Integer> maxHeap = new PriorityQueue<>(Comparator.reverseOrder()); 

PriorityQueue:默认是最小堆 ,需要设置过之后,才能成为最大堆。

 

扩展:使用最大堆(或最小堆)查找最小(或最大)的k个数,比较适合处理海量数据。因为内存的限制,通常不能一次全部载入所有输入数据到内存中。因此,可以每次只读取一部分数据,使用堆来维持目前已知的状态。

关键点:最大堆,最小堆,前k个数

时间复杂度:O(nlog(k)),维持堆有序需要O(log(k))
 

public class LeastNumbersOfK
{
    public static void main(String[] args)
    {
        int[] input = {4, 5, 1, 6, 2, 7, 3, 8};
        int k = 4;
        ArrayList<Integer> result = getKthLeastNumbers(input, k);
        System.out.println(result);
    }

    private static ArrayList<Integer> getKthLeastNumbers(int[] input, int k)
    {
        if (input == null) return new ArrayList<>();
        int length = input.length;
        if (length == 0 || k <= 0 || k > length) return new ArrayList<>();
        //最大堆
        Queue<Integer> maxHeap = new PriorityQueue<>(Comparator.reverseOrder());
        for (int currentValue : input)
        {
            if (maxHeap.size() < k)
            {
                maxHeap.add(currentValue);
            } else
            {
                //当前值比最大堆中的最大值小,则用当前值替换最大值
                if (currentValue < maxHeap.peek())
                {
                    maxHeap.poll();  //移除最大值
                    maxHeap.add(currentValue);  //添加当前值
                }
            }
        }
        return new ArrayList<>(maxHeap);
    }
}

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值