大顶堆和小顶堆

本文介绍了堆这种非线性数据结构,详细阐述了大顶堆和小顶堆的区别,并展示了如何利用Java的PriorityQueue实现寻找数组中前K个最小或最大的元素。通过创建小顶堆,可以在O(n log k)的时间复杂度内解决TopK问题,提高了效率。
摘要由CSDN通过智能技术生成

一、什么是堆?

堆是一种非线性结构,可以把堆看作一棵二叉树,也可以看作一个数组,即:堆就是利用完全二叉树的结构来维护的一维数组。
堆可以分为大顶堆和小顶堆。
大顶堆:每个结点的值都大于或等于其左右孩子结点的值。
小顶堆:每个结点的值都小于或等于其左右孩子结点的值。
如果是排序,求升序用大顶堆,求降序用小顶堆。
一般我们说 topK 问题,就可以用大顶堆或小顶堆来实现,
最大的 K 个:小顶堆
最小的 K 个:大顶堆这里是引用

二、PriorityQueue

在这里插入图片描述

常用的方法:
在这里插入图片描述
大根堆的构造

 PriorityQueue<Integer> q = new PriorityQueue<>((o1,o2)->o2.compareTo(o1))

小根堆的构造

 PriorityQueue<Integer> q = new PriorityQueue<>((o1,o2)->o1.compareTo(o2))

在这里插入图片描述
思考:首先能够想到的是求一个数组中前k个最小的数,并返回到该数组中。直接对该数组进行排序:Arrays.sort(input); 然后遍历前k个存入到res中,返回即可。但这样其实时间复杂读更高,既然是TopK的问题,我们不难想到用小顶堆的方式。

public ArrayList<Integer> GetLeastNumbers_Solution(int [] input, int k) {
        ArrayList<Integer> res = new ArrayList<Integer>();
        // 排除特殊情况
        if(k == 0||input.length==0) return res;
        // 大根堆
        PriorityQueue<Integer> q = new PriorityQueue<>((o1,o2)->o2.compareTo(o1));
        // 创建一个k个大小的堆
        for(int i = 0;i<k;i++){
            q.add(input[i]);
        }
        for(int i = k;i<input.length;i++){
            if(q.peek()>input[i]){
                q.poll();
                q.add(input[i]);
            }
        }
        // 堆中元素取出入数组
        for(int i =0;i<k;i++){
            res.add(q.poll());
        }
        return res;
        
    }
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值