23.Merge k Sorted Lists

题目链接

题目大意:合并多个有序链表成为一个有序单链表。21题是合并两个有序链表。例子如下:

法一(借鉴):利用优先队列构造最小堆,首先将k个链表的首结点入堆,构建初始堆,然后取出堆顶元素,即最小的元素,加入结果链表中,然后将堆顶元素的下一个节点加入堆中,再取出堆顶元素,继续操作,这样就保证了每次都是取最小元素入堆。代码如下(耗时11ms):

 1     public ListNode mergeKLists(ListNode[] lists) {
 2         if(lists.length == 0) {
 3             return null;
 4         }
 5         //定义最小堆
 6         PriorityQueue<ListNode> q = new PriorityQueue<ListNode>(11, new Comparator<ListNode>() {
 7             public int compare(ListNode n1, ListNode n2) {
 8                 return n1.val - n2.val;
 9             }
10         });
11         //初始化最小堆,将k个链表的首节点放入堆中
12         for(int i = 0; i < lists.length; i++) {
13             if(lists[i] != null) {
14                 q.offer(lists[i]);
15             }
16         }
17         ListNode head = new ListNode(0), cur = head;
18         while(!q.isEmpty()) {
19             //取出堆顶元素尾插,即将堆中最小值插入结果链表中
20             cur.next = q.poll();
21             cur = cur.next;
22             //将堆顶元素的下一个元素加入堆中,即原链表中的下一个元素
23             if(cur.next != null) {
24                 q.offer(cur.next);
25             }
26         }
27         return head.next;
28     }
View Code

法二(借鉴):分治。每次归并n/2个链表,如果有6个链表,归并1,4和2,5和3,6。这样最后得到的结果链表一定在1中。当然也可以逐一归并,即1,2和3,4和5,6。是一样的。代码如下(耗时9ms):

 1     public ListNode mergeKLists(ListNode[] lists) {
 2         if(lists.length == 0) {
 3             return null;
 4         }
 5         int n = lists.length;
 6         while(n > 1) {
 7             //每次都取一半进行归并
 8             int mid = (n + 1) / 2;
 9             //如果是6个链表,则归并1,4和2,5和3,6,如此归并最后得到的结果链表一定在1中
10             for(int i = 0; i < n / 2; i++) {
11                 lists[i] = mergeLists(lists[i], lists[mid + i]);
12             }
13             n = mid;
14         }
15         //返回最后的结果链表
16         return lists[0];
17     }
18     //合并两个链表
19     public static ListNode mergeLists(ListNode l1, ListNode l2) {
20         ListNode head = new ListNode(0), cur = head;
21         while(l1 != null && l2 != null) {
22             if(l1.val < l2.val) {
23                 cur.next = l1;
24                 l1 = l1.next;
25             }
26             else {
27                 cur.next = l2;
28                 l2 = l2.next;
29             }
30             cur = cur.next;
31         }
32         if(l1 != null) {
33             cur.next = l1;
34         }
35         if(l2 != null) {
36             cur.next = l2;
37         }
38         return head.next;
39     }
View Code
原文地址:https://www.cnblogs.com/cing/p/9334392.html