首页 > 编程语言 >力扣23(java)-合并k个升序链表(困难)

力扣23(java)-合并k个升序链表(困难)

时间:2022-09-24 16:35:55浏览次数:49  
标签:ListNode val int lists next 链表 升序 java

题目:

给你一个链表数组,每个链表都已经按升序排列。

请你将所有链表合并到一个升序链表中,返回合并后的链表。

 示例 1:

输入:lists = [[1,4,5],[1,3,4],[2,6]]
输出:[1,1,2,3,4,4,5,6]
解释:链表数组如下:
[
1->4->5,
1->3->4,
2->6
]
将它们合并到一个有序链表中得到。
1->1->2->3->4->4->5->6
示例 2:

输入:lists = []
输出:[]
示例 3:

输入:lists = [[]]
输出:[]
 

提示:

k == lists.length
0 <= k <= 10^4
0 <= lists[i].length <= 500
-10^4 <= lists[i][j] <= 10^4
lists[i] 按 升序 排列
lists[i].length 的总和不超过 10^4

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/merge-k-sorted-lists
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题思路:

参考@【王尼玛】的解题思路

一、小根堆

如图:4个链表中的最小值,一定来自黄色的部分,黄色的部分就是一个小根堆。
这个堆的元素个数是lists中链表的个数,初始时只是将每个链表的头结点放入堆中,建立完初始的堆后,就不断的从堆中获取节点,如果获取到的节点不为空,即还有下一个节点,那么就将下一个节点放到堆中。

代码:

 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 == null || lists.length == 0) return null;
14         PriorityQueue<ListNode> queue = new PriorityQueue(new Comparator<ListNode>(){
15             public int compare(ListNode l1, ListNode l2){
16                 //升序
17                 return l1.val - l2.val;
18             }
19         });
20         ListNode dummy = new ListNode(0);
21         ListNode cur = dummy;
22         //把每个链表的头结点放进队列中
23         for(ListNode node: lists){
24             if(node != null){
25                 queue.add(node);
26             }
27         }
28         while(!queue.isEmpty()){
29             cur.next = queue.poll();
30             cur = cur.next;
31             //将当前结点的下一个结点也放入队列中
32             if(cur.next != null){
33                 queue.add(cur.next);
34             }
35         }
36         return dummy.next;
37     }
38 }

 二、分治和合并

先将整个链表在中间进行拆分成两部分,然后再对这两部分继续拆分,直到拆分成最小单元(只有一个链表)时,再进行两两进行合并,合并后以当前合并后的链表为新的链表再与其他的链表进行合并。看图更容易理解

 代码:

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode mergeKLists(ListNode[] lists) {
        if(lists == null || lists.length == 0) return null;
        return mergeTwolists(lists, 0, lists.length - 1);
    }
    //分治
    private ListNode mergeTwolists(ListNode[] lists, int start, int end){
        if(start == end){
            return lists[start];
        }
        int mid = start + (end - start) / 2;
        ListNode l1 = mergeTwolists(lists, start, mid);
        ListNode l2 = mergeTwolists(lists, mid+1, end);
        return merge(l1, l2);
    }
    //合并    
    private ListNode merge(ListNode a, ListNode b){
        if(a == null || b == null){
            return (a == null) ? b : a;
        }
        if(a.val < b.val){
            a.next = merge(a.next, b);
            return a;
        }else{
            b.next = merge(a, b.next);
            return b;
        }

    }
}

标签:ListNode,val,int,lists,next,链表,升序,java
From: https://www.cnblogs.com/liu-myu/p/16725887.html

相关文章

  • my.java
    packagecn.ac.cti.txfz.common.szs;importcn.ac.cti.txfz.common.constant.BaseEnum;importcn.ac.cti.txfz.common.constant.InfoEnum;importio.swagger.annotatio......
  • 二 Java流程控制
    java流程控制Scanner对象实现程序和人的交互,通过Scanner类来获取用户的输入。Scanners=newScanner(System.in);通过Scanner类的next()与nextLine()方法获取输入......
  • 三 Java方法
    Java方法什么是方法Java方法是语句的集合,它们在一起执行一个功能。方法是解决一类问题的步骤的有序组合。方法包含于类或对象中。方法在程序中被创建,在其他地方被引......
  • Java基础 (1)
    IJ的使用快捷键:ctrl+d复制当前行到下一行psvmpublicstaticvoidmain(String[]args){}soutSystem.out.println();Java基础1.注释注释包括单行注释,......
  • java static
    1.static关键字的目的:   主要用于内存管理2.static关键字的范围:     1)使用范围:javastatic关键字可以用在变量、方法、代码块和嵌套类伤。   2)作......
  • JavaScript 的闭包(closure)
    以下内容为本人的学习笔记,如需要转载,请声明原文链接微信公众号「englyf」https://www.cnblogs.com/englyf/对于闭包的理解,其实可以归纳为,在创建函数时,同时创建了一个集......
  • 单向链表的介绍和实现思路
    链表的介绍链表在内存中的存储特点链表是以节点的方式来存储,是链式存储每个节点包含data域和next域。next域用来指向下一个节点链表的各个节点不一定是连续存......
  • Java 静态字段和静态方法
    在一个class中定义的字段,我们称之为实例字段。实例字段的特点是,每个实例都有独立的字段,各个实例的同名字段互不影响。还有一种字段,是用static修饰的字段,称为静态字段:stati......
  • Java 包(package) (不重要)
    为了更好地组织类,Java提供了包机制,用于区别类名的命名空间。包的作用1、把功能相似或相关的类或接口组织在同一个包中,方便类的查找和使用。2、如同文件夹一样,包也......
  • Java源码解析库对比:javaparser、qdox、spoon
    Qdox:paul-hammant/qdoxJavaParser:javaparser/javaparserSPOON:INRIA/spoonQdoxJavaParserSPOONGitHub社区1.3kUsers8Contributors328stars⭐45forks3.3......