classSolution: defmergeKLists(self, lists: List[ListNode]) -> ListNode: # merge sort, divide until it's two list then merge bottom up ifnot lists: returnNone if len(lists) == 1: return lists[0] mid = len(lists) // 2 l, r = self.mergeKLists(lists[:mid]), self.mergeKLists(lists[mid:]) return self.merge(l, r) defmerge(self, l, r): ifnot l andnot r: return l dummy = ListNode(-1) p = dummy while l and r: if l.val < r.val: p.next = l l = l.next else: p.next = r r = r.next p = p.next p.next = l or r return dummy.next
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ classSolution { public: ListNode* mergeKLists(vector<ListNode*>& lists){ //divide lists into half, merge every two list together until only one left if(lists.empty()) returnNULL; int n= lists.size(); while(n>1){ int k= (n+1)/2; for(int i= 0; i< n/2; i++){ lists[i]= mergeList(lists[i], lists[i+k]); } n= k; } return lists[0]; } ListNode* mergeList(ListNode* l1, ListNode* l2){ ListNode* head= new ListNode(-1); ListNode* cur= head; while(l1 && l2){ if(l1->val < l2->val){ cur->next= l1; l1= l1->next; } else{ cur->next= l2; l2= l2->next; } cur= cur->next; } if(l1) cur->next= l1; if(l2) cur->next= l2; return head->next; } };
time complexity: $O(nklog(k))$, n: average length of lists, there are k lists. firstly, merge every two list need nk/2; in the next round, the length of list becomes 2n, the number of lists becomes k/2, so the complexity is still nk/2. Keep such rounds until k == 1, that would be log(k) rounds. so the total complexity is $O(nklog(k))$ space complexity: $O(1)$ reference: https://goo.gl/wUqWfW
Solution 2:
Use a priority_queue to implement. Put every head of the list into the priority_queue, it will sort the value automatically.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
classSolution: defmergeKLists(self, lists: List[ListNode]) -> ListNode: ListNode.__eq__ = lambda self, other: self.val == other.val ListNode.__lt__ = lambda self, other: self.val < other.val heap = [] for l in lists: if l: heappush(heap, l) dummy = ListNode(-1) p = dummy while heap: node = heapq.heappop(heap) if node.next: heapq.heappush(heap, node.next) p.next = node p = p.next return dummy.next
classSolution { public: ListNode* mergeKLists(vector<ListNode*>& lists){ priority_queue<ListNode*, vector<ListNode*>, comp> q; for(int i= 0; i< lists.size(); i++){ if(lists[i]) q.push(lists[i]); } ListNode* head= new ListNode(-1); ListNode *cur= head, *tmp= NULL; while(!q.empty()){ tmp= q.top(); //it's the smallest element right now q.pop(); cur->next= tmp; cur = cur->next; if(tmp->next) q.push(tmp->next); } return head->next; } };
time complexity: $O(nlogk)$, n: average length of lists, there are k lists. The height of the priority_queue would be $logk$. space complexity: $O(logk)$ reference: https://goo.gl/nM8sHt