class Solution { public: ListNode *mergeKLists(vector<ListNode *> &lists) { ListNode* merged = NULL; for (int i=0; i<lists.size(); i++) { merged = merge_list(merged, lists[i]); } return merged; } // helper function to merge two sorted lists ListNode* merge_list(ListNode* l1, ListNode* l2) { ListNode* head = NULL; ListNode* tail = NULL; while (l1 != NULL && l2 != NULL) { ListNode* node = NULL; if (l1->val <= l2->val) { node = l1; l1 = l1->next; } else { node = l2; l2 = l2->next; } if (head == NULL) { head = node; tail = node; } else { tail->next = node; tail = node; } } if (l1 != NULL) { if (head == NULL) { head = l1; } else { tail->next = l1; } } if (l2 != NULL) { if (head == NULL) { head = l2; } else { tail->next = l2; } } return head; } };
第二轮:
Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class MyCmp { public: bool operator() (const ListNode* a, const ListNode* b) { return a->val > b->val; } }; class Solution { public: ListNode *mergeKLists(vector<ListNode *> &lists) { priority_queue<ListNode*, vector<ListNode*>, MyCmp> heads; for (int i=0; i<lists.size(); i++) { if (lists[i] == NULL) { continue; } heads.push(lists[i]); } ListNode* head = NULL; ListNode* pre = NULL; ListNode* cur = NULL; while (!heads.empty()) { cur = heads.top(); heads.pop(); if (head == NULL) { head = cur; } else { pre->next = cur; } if (cur->next != NULL) { heads.push(cur->next); } pre = cur; } if (pre != NULL) { pre->next = NULL; } return head; } };
复杂度mnlog(n), m为链表平均长度,n为链表条数。
看了题解也可以使用分治思想分别合并各条链表。时间复杂度和用堆排序的一致,但是空间可以减少到O(1)
1 /** 2 * Definition for singly-linked list. 3 * struct ListNode { 4 * int val; 5 * ListNode *next; 6 * ListNode(int x) : val(x), next(NULL) {} 7 * }; 8 */ 9 class Solution { 10 public: 11 ListNode *mergeKLists(vector<ListNode *> &lists) { 12 int len = lists.size(); 13 if (len < 1) { 14 return NULL; 15 } 16 int end = len; 17 int wpos= 0; 18 while (end > 1) { 19 for (int i=0; i<end; i+=2) { 20 if (i+1 >= end) { 21 lists[wpos++] = lists[i]; 22 break; 23 } 24 lists[wpos++] = mergeLists(lists[i], lists[i+1]); 25 } 26 end = wpos; 27 wpos= 0; 28 } 29 return lists[0]; 30 } 31 32 ListNode* mergeLists(ListNode* ha, ListNode* hb) { 33 ListNode holder(0); 34 ListNode* prev = &holder; 35 while (ha != NULL && hb != NULL) { 36 if (ha->val <= hb->val) { 37 prev->next = ha; 38 ha = ha->next; 39 } else { 40 prev->next = hb; 41 hb = hb->next; 42 } 43 prev = prev->next; 44 } 45 if (ha != NULL) { 46 prev->next = ha; 47 } 48 if (hb != NULL) { 49 prev->next = hb; 50 } 51 return holder.next; 52 } 53 };