https://leetcode.com/problems/merge-k-sorted-lists/
Merge k Sorted Lists
Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.
Code 1:
import heapq # Definition for singly-linked list. # class ListNode(object): # def __init__(self, x): # self.val = x # self.next = None class Solution(object): def mergeKLists(self, lists): """ :type lists: List[ListNode] :rtype: ListNode """ dummy = ListNode(-1) cur = dummy if not lists: return None h = [(lists[i].val, lists[i]) for i in xrange(len(lists)) if lists[i] ] heapq.heapify(h) while len(h) > 0: t = heapq.heappop(h) cur.next = t[1] cur = cur.next if t[1].next: heapq.heappush(h, (t[1].next.val, t[1].next)) return dummy.next
Use a min-heap to store k lists’ heads. Build a heap requires O(k) time. Every time you pop the least value from the heap, and push into that value’s next node into the heap. Since there are N elements in total and each heap push takes O(logK) time, the algorithm takes O(K+NlogK) time (O(K) is for heapify) but also O(K) additional space.
See [1] and [2] why the time complexity of heapify is O(K).
[1] http://stackoverflow.com/questions/9755721/how-can-building-a-heap-be-on-time-complexity
[2] https://www.cs.bgu.ac.il/~ds122/wiki.files/Presentation09.pdf
Code 2:
Use O(NlogK) time and there is no additional space required. Everytime you merge k/2 pairs lists. Reference: https://leetcode.com/discuss/20774/sharing-straightforward-solution-without-structure-vector
class Solution { public: ListNode *mergeTwoLists(ListNode* l1, ListNode* l2) { if (NULL == l1) return l2; else if (NULL == l2) return l1; if (l1->val <= l2->val) { l1->next = mergeTwoLists(l1->next, l2); return l1; } else { l2->next = mergeTwoLists(l1, l2->next); return l2; } } ListNode *mergeKLists(vector<ListNode *> &lists) { if (lists.empty()) return NULL; int len = lists.size(); while (len > 1) { for (int i = 0; i < len / 2; ++i) { lists[i] = mergeTwoLists(lists[i], lists[len - 1 - i]); } len = (len + 1) / 2; } return lists.front(); } };
Similar Idea using Java:
public class Solution { public ListNode mergeTwoLists(ListNode l1, ListNode l2) { if (l1 == null) return l2; if (l2 == null) return l1; ListNode head=null; ListNode former=null; while (l1!=null&&l2!=null) { if (l1.val>l2.val) { if (former==null) former=l2; else former.next=l2; if (head==null) head=former; else former=former.next; l2=l2.next; } else { if (former==null) former=l1; else former.next=l1; if (head==null) head=former; else former=former.next; l1=l1.next; } } if (l2!=null) l1=l2; former.next=l1; return head; } public ListNode mergeKLists(List<ListNode> lists) { if (lists.size()==0) return null; if (lists.size()==1) return lists.get(0); if (lists.size()==2) return mergeTwoLists(lists.get(0), lists.get(1)); return mergeTwoLists(mergeKLists(lists.subList(0, lists.size()/2)), mergeKLists(lists.subList(lists.size()/2, lists.size()))); } }
https://leetcode.com/discuss/9279/a-java-solution-based-on-priority-queue
Reference: