Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.

我们采用分治的方法来解决这个问题,其有K个链表,不断将其划分(partition),再将其归并(merge)。

划分的部分并不难,将其不断分成两部分,但是需要注意的是可能出现start和end相等的情况,这时候就直接return lists[start]就可以了。

mid = (start + end) / 2
start -- mid (1)
mid + 1 -- end (2)

上面的(1)和(2)就不断的替换更新,不断作为参数写到partition函数内。

/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode mergeKLists(ListNode[] lists) {
return partition(lists, 0, lists.length - 1);
}

public ListNode partition(ListNode[] lists, int start, int end) {
if (start == end) {
return lists[start];
}

if (start < end) {
int mid = (start + end) / 2;
ListNode l1 = partition(lists, start, mid);
ListNode l2 = partition(lists, mid + 1, end);
return mergeTwoLists(l1, l2);
}

return null;
}

public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
if (l2 == null) return l1;
if (l1 == null) return l2;

if (l1.val < l2.val) {
ListNode tmp = l1;
tmp.next = mergeTwoLists(l1.next, l2);
return tmp;
} else {
ListNode tmp = l2;
tmp.next = mergeTwoLists(l1, l2.next);
return tmp;
}
}
}

Java2

/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode mergeKLists(ListNode[] lists) {
if (lists.length == 0) return null;
int interval = 1;
while (interval < lists.length) {
for (int i = 0; i + interval < lists.length; i = i + interval*2) {
lists[i] = mergeTwo(lists[i], lists[i+interval]);
}
interval *= 2;
}
return lists[0];
}

ListNode mergeTwo(ListNode l1, ListNode l2) {
ListNode result = new ListNode(0);
ListNode temp = result;
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;
}
}
if (l1 != null) temp.next = l1;
if (l2 != null) temp.next = l2;
return result.next;
}
}