漫步计算机系统之数据结构与算法(10)堆和队列
问题一: 给定一个数组,找出其中最小的K个数。例如数组元素是4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4。
代码如下:
public ArrayList GetLeastNumbers_Solution(int[] nums, int k) {
if (k > nums.length || k <= 0)
return new ArrayList<>();
PriorityQueue maxHeap = new PriorityQueue<>((o1, o2) -> o2 - o1);
for (int num : nums) {
maxHeap.add(num);
if (maxHeap.size() > k)
maxHeap.poll();
}
return new ArrayList<>(maxHeap);
}
算法描述: 从头至尾迭代数组; 将数组元素压入最大堆maxHeap; 若压入的数量超出了K,弹出堆的根元素,即队中最大值元素; 迭代结束,堆maxHeap中保存的即为最小的K个元素。
问题二: 得到一个数据流中的中位数
代码如下:
/* 大顶堆,存储左半边元素 */
private PriorityQueue left = new PriorityQueue<>((o1, o2) -> o2 - o1);
/* 小顶堆,存储右半边元素,并且右半边元素都大于左半边 */
private PriorityQueue right = new PriorityQueue<>();
/* 当前数据流读入的元素个数 */
private int N = 0;
public void Insert(Integer val) {
/* 插入要保证两个堆存于平衡状态 */
if (N % 2 == 0) {
/* N 为偶数的情况下插入到右半边。
* 因为右半边元素都要大于左半边,但是新插入的元素不一定比左半边元素来的大,
* 因此需要先将元素插入左半边,然后利用左半边为大顶堆的特点,取出堆顶元素即为最大元素,此时插入右半边 */
left.add(val);
right.add(left.poll());
} else {
right.add(val);
left.add(right.poll());
}
N++;
}
public Double GetMedian() {
if (N % 2 == 0)
return (left.peek() + right.peek()) / 2.0;
else
return (double) right.peek();
}
算法描述: 设置一个大顶堆left和小顶堆right; 当数据流的个数为偶数,将输入的数插入大顶堆left,并将大顶堆的根元素弹出插入小顶堆right; 当数据流的个数为奇数,将输入的数插入小顶堆right,并将大顶堆的根元素弹出插入大顶堆left; 这样right里面的数都比left里面的数大,若数据流个数为偶数,要获得中位数大小,取left和right根元素的平均值; 若数据流个数为奇数,此时right里元素比left里刚好多一个,要获得中位数大小,取right根元素值即可。
问题三:字符流中第一个不重复的字符
请实现一个函数用来找出字符流中第一个只出现一次的字符。例如,当从字符流中只读出前两个字符 "go" 时,第一个只出现一次的字符是 "g"。当从该字符流中读出前六个字符"google" 时,第一个只出现一次的字符是 "l"。
代码如下:
private int[] cnts = new int[128];
private Queue queue = new LinkedList<>();
public void Insert(char ch) {
cnts[ch]++;
queue.add(ch);
while (!queue.isEmpty() && cnts[queue.peek()] > 1)
queue.poll();
}
public char FirstAppearingOnce() {
return queue.isEmpty() ? "#" : queue.peek();
}
算法描述: 定义一个128位的整型数组cnts(每个元素代表一个ASCII码字符),以及一个字符型队列queue; 每输入一个字符,该字符对应的cnts位元素值加1; 将该字符入队列queue; 从头至尾迭代队列queue,若队列字符对应的cnts位元素值大于1,队列头元素弹出; 此时队列的头元素即为字符流中第一个不重复的字符。
问题四:滑动窗口的最大值
例如,如果输入数组 {2, 3, 4, 2, 6, 2, 5, 1} 及滑动窗口的大小 3,那么一共存在 6 个滑动窗口,他们的最大值分别为 {4, 4, 6, 6, 6, 5}。
代码如下:
public ArrayList maxInWindows(int[] num, int size) {
ArrayList ret = new ArrayList<>();
if (size > num.length || size < 1)
return ret;
PriorityQueue heap = new PriorityQueue<>((o1, o2) -> o2 - o1); /* 大顶堆 */
for (int i = 0; i < size; i++)
heap.add(num[i]);
ret.add(heap.peek());
for (int i = 0, j = i + size; j < num.length; i++, j++) { /* 维护一个大小为 size 的大顶堆 */
heap.remove(num[i]);
heap.add(num[j]);
ret.add(heap.peek());
}
return ret;
}
算法描述: 设置一个最大堆heap,窗口大小为size; 先将数组中前size个元素入堆中,得到根元素为第一个窗口的最大值,入最大值链表; 将窗口第一个元素从堆中删除,即将窗口向前移动一位;窗口最右边的新元素入堆中,再将此时堆中根元素入最大值链表; 迭代至窗口滑动到最右边,返回最大值链表,程序结束。
注:凡属于本公众号内容,未经允许不得私自转载,否则将依法追究侵权责任。
华尔街英语暴雷!企业如何避免陷入资金危机?华尔街英语本周将正式宣布破产上周,老牌成人英语培训机构华尔街英语被曝出将正式宣布破产,线下门店现已陆续关闭。在广州,包括华尔街英语广州公园前中心华尔街英语广州珠江新城中心华尔街英语
大有可为,设计新生报到必备!戴尔灵越16Plus上手体验2021年的高考刚刚落下帷幕,今年又将有数百万的学生步入大学生活。对于学生党来说,一台笔记本电脑将会是接下来学习,生活,甚至未来工作必备的工具。尤其是设计类,传媒类,动画类专业的学
朱耿洲高利贷入刑,民间资本路在何方?对高利贷进行严格的法律约束央视曾曝光714高炮乱象。714高炮就是所谓借款期限只有7天或者14天,金额在500到1000元不等,且带有高额砍头息的各种贷款产品。有用户拆东墙补西墙,
创维两款重磅电视新品,科技堆料堪比三星小米,设计犹如华为苹果3月31日,创维电视登峰造极春季新品发布会在京举行,董事长王志国表示电视行业相较手机来讲还是冷门,但创维却取得了业界少有的显著增长,同时表示创维电视致力于打造高端产品理念,并强调创
新网企业邮箱培训小课堂开讲啦用了企业邮箱好多年,才发现还能这样操作?面临突发的邮箱情况,不知道怎么解决?新网邮箱知识小课堂开讲啦,您的邮箱小疑惑这里统统给您解答。问邮件发送有什么要注意的吗?小邮提示您1发送邮
百威啤酒进军NFT?30枚以太币拿下Beer。eth新网域名资讯NFT区块链概念爆火之后,越来越多不同行业的企业终端都开始进入NFT领域,而相关域名等数字资产,商业价值也是一路飙升。据外媒报道,百威啤酒以30枚以太币收购了ENS域名
各大平台解除屏蔽外链域名通行将不再受阻新网域名资讯私域流量概念的兴起已经有好几年了,作为我国数字经济时代流量到顶的必然结果,企业品牌要想实现业绩的持续增长,必须注重自身流量池的增长。即时通讯软件作为大众的沟通平台,承担
网站验收指南,带您少走弯路新网建站资讯目前,定制建站第三方建站已经成为建站的主流模式,但是建站行业技术价格服务等没有统一行业标准,因此,很多企业在首次建站的时候,都会面临不知道如何交付的问题。因为对方说的压
曾高达350万元易主!单字母域名Q。org被启用新网域名资讯有消息称,今年初,域名Q。org被启用,并推出了Q区块链。这是一个基于以太坊技术的开源项目,该区块链是一个公共开放去中心化的分类账本,其治理理念已经在法律体系中得到了试
小心!您的响应式网站可能是假的新网建站资讯响应式网页已经成为当下比较主流的设计形式,似乎每一个人都在谈论,但实际上并不是每一个人都真的懂得。往往一些企业被一些鱼龙混杂的小服务商所套路,购买了一套假的响应式网站,
网站需要用多少秒留住用户?新网建站资讯两个陌生人相遇,双方会在35秒内迅速评判对方,产生第一印象。是不是很残酷?他她对你的初步评价5秒钟就完成了。这个第一印象的规律引发了小新的思考,网站建设是不是也是同理?