原题链接: https://leetcode.com/problems/merge-k-sorted-lists/
相似题目:
21. Merge Two Sorted Lists
1. 题目介绍:
Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.
合并 k 个有序链表到一个链表中,合并后的新链表也必须是有序的。分析采用方法的复杂度.
Example:
Input:
[
1->4->5,
1->3->4,
2->6
]
Output: 1->1->2->3->4->4->5->6
2. 解题思路
2.1 方法1:不停地合并2个链表
这道题是合并2个有序链表 21. Merge Two Sorted Lists 的加强版。
所以很自然地,就可以使用21. Merge Two Sorted Lists 合并2个链表的方法,不停地合并数组中的链表,最终实现合并所有的链表。
在合并2个链表的题目中,采取的做法是新建一个链表,然后同时遍历2个链表,取其中较小的值放入新链表。
实现代码
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode mergeKLists(ListNode[] lists) {
ListNode ans = new ListNode(0);
int length = lists.length;
if(length == 0){
return ans.next;
}
ans.next = lists[0];
for(int i = 1 ; i < length ; i++){
ans.next = mergeTwoLists(ans.next, lists[i] );
}
return ans.next;
}
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
ListNode assist = new ListNode(0);
ListNode cur = assist;
while( l1 != null || l2 != null){
int a = (l1 == null ? Integer.MAX_VALUE : l1.val);
int b = (l2 == null ? Integer.MAX_VALUE : l2.val);
if(a < b){
cur.next = new ListNode( a );
l1 = (l1 == null ? null: l1.next);
}else{
cur.next = new ListNode( b );
l2 = (l2 == null ? null: l2.next);
}
cur = cur.next;
}
return assist.next;
}
}
2.2 方法2:使用分治法合并2个链表
注: 本方法的思路来自LeetCode的官方Solution,有兴趣的读者可以去看原文: https://leetcode.com/problems/merge-k-sorted-lists/solution/
这个方法和方法1非常像。但是方法1是从第一个链表开始合并,一直按照顺序合并到最后一个链表。假设k是链表的个数,那么一共需要合并 k - 1次。
如果采用分治法,每两个相邻的链表先合并,合并后的新链表再和旁边新合并形成的链表合并。这样只需要合并 log k 次。
实现代码
class Solution {
public ListNode mergeKLists(ListNode[] lists) {
int length = lists.length;
if (length == 0) {
return null;
}
return DivideAndConquer( lists, 0 , length-1 );
}
public ListNode DivideAndConquer(ListNode[] lists, int a,int b){
if (a == b) {
return lists[a];
}
int middle = (a + b) / 2 ;
ListNode left = DivideAndConquer(lists, a , middle);
ListNode right = DivideAndConquer(lists, middle+1 , b );
return mergeTwoLists(left,right);
}
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
ListNode assist = new ListNode(0);
ListNode cur = assist;
while( l1 != null || l2 != null){
int a = (l1 == null ? Integer.MAX_VALUE : l1.val);
int b = (l2 == null ? Integer.MAX_VALUE : l2.val);
if(a < b){
cur.next = new ListNode( a );
l1 = (l1 == null ? null: l1.next);
}else{
cur.next = new ListNode( b );
l2 = (l2 == null ? null: l2.next);
}
cur = cur.next;
}
return assist.next;
}
}