Java优先队列PriorityQueue

本文介绍了贪心算法在分糖果问题中的应用,以及如何利用最大堆实现优先队列,如PriorityQueue的原理和方法。详细解读了最大堆和最小堆的概念,以及它们在数据结构中的作用。通过实例展示了如何结合这两个概念解决实际问题。
摘要由CSDN通过智能技术生成

今天刷力扣每日一题的时候遇到了一个“重构字符串的问题”,我在观阅题解后发现是用贪心算法+最大堆来解决的,于是恶补了这两方面的知识:

关于最大(小)堆

最大(小)堆是指在树中,存在一个结点而且该结点有儿子结点,该结点的data域值都不小于(大于)其儿子结点的data域值,并且它是一个完全二叉树。

这里不免就有人问了:完全二叉树的定义又是什么?

完全二叉树

不用多说先上图:
在这里插入图片描述
上面列举了几种典型的完全二叉树的误区图和辨识图,这里我再通俗地定义一下:
1.首先是二叉树
2.去除最底的两层,上面部分是一个满二叉树
3.最下两层节点的度可以小于二且最下面一层的叶子节点依次排列在最左层(如图c来说若6,7依次是4节点的左右子节点而不是5的子节点,则它也是完全二叉树)
在我搜索最大(小)堆的相关资料时,发现队列的一个实现类是根据最大(小)堆来玩的,这里引出了标题:

优先队列PriorityQueue

一.简介
我们都知道队列是先进先出的,而对于优先队列,数据是按照特定顺序来进行有序排列,插入新数据时会自动插入到合适位置保证队列有序。(根据debug测试除了插入相同的数据,依次往PriorityQueue中插入数据时还是按照排序前的顺序来存入地址的如下图所示)
在这里插入图片描述
二.基于堆实现
优先队列底层时根据二叉堆实现的,如图所示:在这里插入图片描述
其实如图所示就是上面所说的最大堆最小堆,而优先队列默认时按照最大堆(a)来排序,即插入数据时会把最大值放在根上。
三.常用方法列举
PriorityQueue.pool()方法:会将排序队列中最小值的节点出队,返回值为此节点的值。
PriorityQueue.peek()方法:返回队列的头元素(即队列中最小值)。
PriorityQueue.offer()方法:往队列内插入元素。

贪心算法

接下来我们讲讲贪心算法:
贪心算法是一种重要的解决问题的思想,它是指在对问题求解时,总是做出在当前看来时最好的选择。也就是说,不从整体最优上加以考虑,它所做出的仅仅是在某种意义上的局部最优解
贪心算法没有固定的算法框架,算法设计的关键是贪心策略的选择。必须注意的是,贪心算法不是对所有问题都能得到整体最优解,选择的贪心策略必须具备无后效性(即某个状态以后的过程不会影响以前的状态,只与当前状态有关。)
用一个例题熟悉一下:
1.力扣的455题,分糖果问题
题目:已知一些孩子和一些糖果,每个孩子有需求因子g,每个糖果有大小s,当某个糖果的大小s>=某个孩子的需求因子g时,代表该糖果可以满足该孩子,求使用这些糖果,最多能满足多少孩子(注意,某个孩子最多只能用1个糖果满足)
这里的基本思想就是贪心思想,对题解算法设计如下两点:
1.对需求因子数组g和糖果大小数组s进行从小到大的排序
2.按照从小到大的顺序使用各糖果尝试是否可满足某个孩子,每个糖果只尝试1次,只有尝试成功时,换下一个孩子尝试,直到发现没更多的孩子或者没有更多的糖果,循环结束。
附上代码:

class Solution {
    //贪心的思想是,用尽量小的饼干去满足小需求的孩子,所以需要进行排序先
    public int findContentChildren(int[] g, int[] s) {
        int child = 0;
        int cookie = 0;
        Arrays.sort(g);  //先将饼干 和 孩子所需大小都进行排序
        Arrays.sort(s);
        while (child < g.length && cookie < s.length ){ //当其中一个遍历就结束
            if (g[child] <= s[cookie]){ //当用当前饼干可以满足当前孩子的需求,可以满足的孩子数量+1
                child++;
            }
            cookie++; // 饼干只可以用一次,因为饼干如果小的话,就是无法满足被抛弃,满足的话就是被用了
        }
        return child; 
    }
}

这里我只是大致讲解了下最大最小堆和优先队列,而掌握一门知识不仅要会用,还要弄懂,这里我介绍两篇我个人认为很好的博客,有兴趣的小伙伴可以了解了解:
详解最大堆:https://www.jianshu.com/p/21bef3fc3030
优先队列PriorityQueue:https://blog.csdn.net/qq_35326718/article/details/72866180

贪心算法:https://blog.csdn.net/bajin7353/article/details/80703727
https://www.jianshu.com/p/ab89df9759c8

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值