• 算法通关村第14关【白银】| 堆的经典问题


    1.数组中的第k个最大元素

    思路:

    • 最直观的就是选择法,遍历一k次找到第k大的数
    • 之前使用快速排序的思想每次找出一个位置,会超时
    • 这里使用堆(优先队列),找最大用小堆,找最小用大堆。

    例如找第k大的数,新建一个空间为k的最小优先队列,只要比当前优先队列最小值大就替换进去,这样全部的数遍历一遍,里面留下的就是前k大的数了,其他的全被替换出去了,并且队头是第k最大的。

    1. class Solution {
    2. public int findKthLargest(int[] nums, int k) {
    3. PriorityQueue pq = new PriorityQueue<>(k);
    4. for(int n : nums){
    5. if(pq.size()
    6. pq.offer(n);
    7. }else{
    8. if(n>pq.peek()){
    9. pq.poll();
    10. pq.offer(n);
    11. }
    12. }
    13. }
    14. return pq.peek();
    15. }
    16. }

    2.堆排序原理

    1. 构建最大堆(Max Heap):首先,将待排序的元素构建成一个最大堆。最大堆是一个满足堆性质的二叉树,即每个节点的值都大于或等于其子节点的值,根节点是堆中的最大元素。

      构建最大堆的过程:从数组中的最后一个非叶子节点开始,逐个向前处理每个节点,将当前节点与其子节点比较并进行交换,直到整个数组构建成一个最大堆。
    2. 排序:一旦构建了最大堆,最大元素就位于堆的根节点(数组的第一个元素)。将根节点(最大元素)与数组中的最后一个元素交换,然后将数组的大小减1,将根节点下沉到适当位置,以保持剩余元素的最大堆性质。重复这个过程,直到整个数组有序。

     堆排序的时间复杂度为O(n * log n),其中n是待排序数组的元素数量。由于堆排序是一种原地排序算法,不需要额外的辅助空间,因此它在空间复杂度上表现较好。堆排序的稳定性取决于在构建最大堆时是否采用稳定的下沉方法,通常情况下是不稳定的排序算法。

    3.合并k个升序链表

    思路:题目要求从小到大排序构造一个新的链表,这里要保证每次加入的元素是当前最小的,使用优先队列构造小根堆。将ListNode数组第一个元素加入队列,每次取出队头然后加入取出的元素的下一个。

    PriorityQueue详解可以看 PriorityQueue初始化和方法

    1. /**
    2. * Definition for singly-linked list.
    3. * public class ListNode {
    4. * int val;
    5. * ListNode next;
    6. * ListNode() {}
    7. * ListNode(int val) { this.val = val; }
    8. * ListNode(int val, ListNode next) { this.val = val; this.next = next; }
    9. * }
    10. */
    11. class Solution {
    12. public ListNode mergeKLists(ListNode[] lists) {
    13. if(lists.length == 0){
    14. return null;
    15. }
    16. ListNode head = new ListNode(-1);
    17. PriorityQueue q = new PriorityQueue<>(lists.length,(a,b)->a.val-b.val);
    18. for(int i = 0;i
    19. if(lists[i] == null) continue;
    20. q.add(lists[i]);
    21. }
    22. ListNode tail = head;
    23. while(!q.isEmpty()){
    24. tail.next = q.poll();
    25. tail = tail.next;
    26. if(tail.next!=null){
    27. q.offer(tail.next);
    28. }
    29. }
    30. return head.next;
    31. }
    32. }

  • 相关阅读:
    差分+差分矩阵(更适合新手宝宝体质)
    webpack之hot热更新
    cmka下切换使用不同版本的boost-未解决
    Linux设备树 01 ———— 内核笔记
    【老生谈算法】matlab实现apriori算法源码——apriori算法
    记一次线上websocket返回400问题排查
    网络安全(黑客技术)—自学
    深入探讨Python中的主流排序算法
    canal集群部署及使用
    国庆假期作业day2
  • 原文地址:https://blog.csdn.net/Candy___i/article/details/133050882