详解 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));
    }
}

输出结果:

相关推荐
waicsdn_haha2 分钟前
Java/JDK下载、安装及环境配置超详细教程【Windows10、macOS和Linux图文详解】
java·运维·服务器·开发语言·windows·后端·jdk
打鱼又晒网3 分钟前
linux网络套接字 | 深度解析守护进程 | 实现tcp服务守护进程化
linux·网络协议·计算机网络·tcp
_WndProc4 分钟前
C++ 日志输出
开发语言·c++·算法
Q_192849990612 分钟前
基于Spring Boot的摄影器材租赁回收系统
java·spring boot·后端
Code_流苏15 分钟前
VSCode搭建Java开发环境 2024保姆级安装教程(Java环境搭建+VSCode安装+运行测试+背景图设置)
java·ide·vscode·搭建·java开发环境
良许Linux17 分钟前
0.96寸OLED显示屏详解
linux·服务器·后端·互联网
努力学习编程的伍大侠17 分钟前
基础排序算法
数据结构·c++·算法
蜜獾云27 分钟前
docker 安装雷池WAF防火墙 守护Web服务器
linux·运维·服务器·网络·网络安全·docker·容器
小屁不止是运维28 分钟前
麒麟操作系统服务架构保姆级教程(五)NGINX中间件详解
linux·运维·服务器·nginx·中间件·架构
bitcsljl42 分钟前
Linux 命令行快捷键
linux·运维·服务器