Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.
Example:
Input:
[
1->4->5,
1->3->4,
2->6
]
Output: 1->1->2->3->4->4->5->6
思路1: 用priorityQueue,跟站队一样,每次取队伍的第一个,然后取走后,后面的补上;O(Nlogk)
/**
* 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) {
PriorityQueue<ListNode> pq = new PriorityQueue<ListNode>((a, b) -> (a.val - b.val));
for(ListNode node: lists) {
if(node != null) {
pq.offer(node);
}
}
ListNode dummpy = new ListNode(-1);
ListNode cur = dummpy;
while(!pq.isEmpty()) {
ListNode node = pq.poll();
cur.next = node;
cur = node;
if(node.next != null) {
pq.offer(node.next);
}
}
return dummpy.next;
}
}
思路2:divide and conquer,这个非常有效果;O(NlogK)
别忘记 start == end 的 base情况;
/**
* 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 mergeK(lists, 0, lists.length - 1);
}
private ListNode mergeK(ListNode[] lists, int start, int end) {
if(start > end) {
return null;
}
if(start == end) {
return lists[start];
}
int mid = start + (end - start) / 2;
ListNode l1 = mergeK(lists, start, mid);
ListNode l2 = mergeK(lists, mid + 1, end);
return mergeTwoLists(l1, l2);
}
public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
ListNode dummpy = new ListNode(-1);
ListNode cur = dummpy;
while(list1 != null && list2 != null) {
if(list1.val < list2.val) {
cur.next = list1;
list1 = list1.next;
} else {
cur.next = list2;
list2 = list2.next;
}
cur = cur.next;
}
if(list1 != null) {
cur.next = list1;
}
if(list2 != null) {
cur.next = list2;
}
return dummpy.next;
}
}