题意:合并k个有序的链表,分析描述算法的复杂度。
分析:这道题目在分布式系统中非常常见,来自不同client的sorted list要在central server上面merge起来。解法就是有点类似于归并排序的思路,就是分治法,不了解归并排序的朋友,请参见归并排序-维基百科,是一个比较经典的O(nlogn)的排序算法,还是比较重要的。
思路是先分成两个子任务,然后递归求子任务,最后回溯回来。这个题目也是这样,先把k个list分成两半,然后继续划分,知道剩下两个list就合并起来,合并时需要用到两个有序的链表子过程。不熟悉的朋友可以复习一下。代码如下:
class Solution {
public static ListNode mergeKLists(ListNode[] lists) {
if(lists.length == 0) return null;
return help(lists, 0, lists.length - 1);
}
public static ListNode help(ListNode[] lists, int l, int r) {
int m = (l + r) / 2;
if(l < r){
return mergeTwoLists(help(lists, l, m), help(lists, m + 1, r));
}
return lists[l];
}
public static ListNode mergeTwoLists(ListNode l1, ListNode l2) {
if(l1 == null || l2 == null) return l1==null? l2:l1;
ListNode dummy = new ListNode(0);
if(l1.val < l2.val){
dummy.next = l1;
l1 = l1.next;
}else{
dummy.next = l2;
l2 = l2.next;
}
ListNode temp = dummy.next;
while(l1 != null && l2 != null){
if(l1.val < l2.val){
temp.next = l1;
temp = temp.next;
l1 = l1.next;
}else{
temp.next = l2;
temp = temp.next;
l2 = l2.next;
}
}
temp.next = l1 == null ? l2:l1;
return dummy.next;
}
public static void print(ListNode head){
while(head != null){
System.out.println(head.val);
head = head.next;
}
}
public static void main(String[] args) {
ListNode l1 = new ListNode(4);
ListNode l2 = new ListNode(5);
ListNode l3 = new ListNode(6);
ListNode l4 = new ListNode(1);
ListNode l5 = new ListNode(2);
ListNode l6 = new ListNode(3);
l1.next = l2;
l2.next = l3;
l4.next = l5;
l5.next = l6;
ListNode[] lists = {l1,l4};
print(mergeKLists(lists));
}
}