详解 leetcode_078. 合并K个升序链表.小顶堆实现

java 复制代码
/**
 * 构造单链表节点
 */
class ListNode{
     int value;//节点值
     ListNode next;//指向后继节点的引用
    public ListNode(){}
    public ListNode(int value){
        this.value=value;
    }
    public ListNode(int value,ListNode next){
        this.value=value;
        this.next=next;
    }
}


package com.ag;
import java.util.ArrayList;
import java.util.List;
import java.util.PriorityQueue;
import java.util.Queue;

/**
 *  leetcode_078. 合并K个升序链表
 *  解题思路:
 *  1.定义小根堆的大小为K,然后从每个链表拿一个元素进来构造最小堆
 *  2.取走堆顶元素(一定是最小值)插入到新链表的表尾,然后将该元素所在的链表再拿一个元素进来,重新构造小顶堆
 *
 */
public class MergeKASCList {
    public ListNode mergeKLists(List<ListNode> lists){
       //1.判断边界
        if(lists==null||lists.size()==0){
            return null;
        }

        //2.构造最小堆
        Queue<ListNode> minHeap=new PriorityQueue<>((o1, o2) -> o1.value-o2.value);
        for (ListNode listNode : lists) {
            if(listNode!=null){
                minHeap.offer(listNode);//元素入堆
            }
        }

        //3.构造合并后的新链表
        ListNode head=new ListNode(0);
        ListNode tail=head;
        while (!minHeap.isEmpty()){
            //堆顶元素出堆,获取链表最小节点,加入新链表队尾
            tail.next=minHeap.poll();
            tail=tail.next;

            if(tail.next!=null){
                minHeap.offer(tail.next);//最小链表节点的下一个节点加入最小堆 (重新构造小顶堆)
            }
        }
        return head.next;
    }

    public static void main(String[] args) {
        List<ListNode> lists=new ArrayList<>();

        //1.初始化各个节点
        ListNode node1=new ListNode(1);
        ListNode node2=new ListNode(4);
        ListNode node3=new ListNode(5);

        ListNode node4=new ListNode(1);
        ListNode node5=new ListNode(3);
        ListNode node6=new ListNode(4);

        ListNode node7=new ListNode(2);
        ListNode node8=new ListNode(6);

        //2.构建节点之间的引用
        node1.next=node2;
        node2.next=node3;

        node4.next=node5;
        node5.next=node6;

        node7.next=node8;

        //打印链表
//        printLinkedList(node1);
//        printLinkedList(node4);
//        printLinkedList(node7);

        //3.将链表头节点添加到list
        lists.add(node1);
        lists.add(node4);
        lists.add(node7);

        //4.合并链表
        MergeKASCList mergeKASCList=new MergeKASCList();
        ListNode listNode=mergeKASCList.mergeKLists(lists);

        //5.打印合并后的链表
        printLinkedList(listNode);
    }

    /**
     * 打印链表
     * @param head
     */
    public static void printLinkedList(ListNode head) {
        List<String> list = new ArrayList<>();
        while (head != null) {
            list.add(String.valueOf(head.value));
            head = head.next;

        }
        System.out.println(String.join(" -> ", list));
    }
}

输出结果:

相关推荐
若鱼191915 分钟前
SpringBoot4.0新特性-Observability让生产环境更易于观测
java·spring
Trouvaille ~22 分钟前
【Linux】TCP Socket编程实战(一):API详解与单连接Echo Server
linux·运维·服务器·网络·c++·tcp/ip·socket
觉醒大王24 分钟前
强女思维:着急,是贪欲外显的相。
java·论文阅读·笔记·深度学习·学习·自然语言处理·学习方法
偷吃的耗子28 分钟前
【CNN算法理解】:CNN平移不变性详解:数学原理与实例
人工智能·算法·cnn
努力学编程呀(๑•ี_เ•ี๑)32 分钟前
【在 IntelliJ IDEA 中切换项目 JDK 版本】
java·开发语言·intellij-idea
码农小卡拉41 分钟前
深入解析Spring Boot文件加载顺序与加载方式
java·数据库·spring boot
向上的车轮1 小时前
为什么.NET(C#)转 Java 开发时常常在“吐槽”Java:checked exception
java·c#·.net
Dragon Wu1 小时前
Spring Security Oauth2.1 授权码模式实现前后端分离的方案
java·spring boot·后端·spring cloud·springboot·springcloud
跳动的梦想家h1 小时前
环境配置 + AI 提效双管齐下
java·vue.js·spring
坚持就完事了1 小时前
Java中的集合
java·开发语言