Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.數據結構
第一反應是採用敗者樹的merge模式,可是敗者樹的數據結構也就在大二時學過,早忘了細節,實現麻煩。模擬了一下,每次merge最小的兩個鏈,可是選鏈是每次排序後選擇的,有一個case是每條鏈都是一個字符,鏈不少,因而超時了。起始也能夠改進一下將排序改成鏈表結構的插入排序。更好的是改成Heap結構。沒有實施。
改成兩路merge的方式,經過遞歸實現很簡單。code
耗時:26ms排序
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ struct List { ListNode* head; int len; }; bool ListCmp(List& l1, List& l2) { return l1.len > l2.len; } class Solution { public: ListNode* mergeKLists(vector<ListNode*>& lists) { return mergeKListsTwoRoad(lists, 0, lists.size()); ListNode* ret = NULL; return ret; } /////////Two Road Merge/////////// ListNode* mergeKListsTwoRoad(vector<ListNode*>& lists, int s, int e) { if (s >= e) return NULL; if (s + 1 == e) return lists[s]; int sz = e - s; int sz1 = sz / 2; ListNode* p1 = mergeKListsTwoRoad(lists, s, s + sz1); ListNode* p2 = mergeKListsTwoRoad(lists, s + sz1, e); return mergeList(p1, p2); } ListNode* mergeList(ListNode* p1, ListNode* p2) { if (p1 == NULL) return p2; if (p2 == NULL) return p1; ListNode* head = NULL; if (p1->val < p2->val) { head = p1; p1 = p1->next; } else { head = p2; p2 = p2->next; } ListNode* p = head; while (p1 != NULL && p2 != NULL) { if (p1->val < p2->val) { p->next = p1; p1 = p1->next; } else { p->next = p2; p2 = p2->next; } p = p->next; } if (p1 != NULL) { p->next = p1; } if (p2 != NULL) { p->next = p2; } return head; } ////////////////////////////////////////version of Time Limit Exceeded //////////////////////////////////// ListNode* mergeKLists_pitch2ShorterEach(vector<ListNode*>& lists) { vector<List> ls; for (int i = 0; i < lists.size(); i++) { List l; l.head = lists[i]; l.len = length(l.head); ls.push_back(l); } sort(ls.begin(), ls.end(), ListCmp); List lr = mergeKLists(ls); return lr.head; } List mergeKLists(vector<List>& ls) { List l; if (ls.size() == 0) return l; if (ls.size() == 1) return ls[0]; while (ls.size() > 1) { List l1 = ls.back(); ls.pop_back(); List l2 = ls.back(); ls.pop_back(); l = mergeList(l1, l2); ls.push_back(l); int i = ls.size() - 2; for (; i >= 0; i--) { List& li = ls[i]; if (li.len < l.len) { ls[i + 1] = ls[i]; } } ls[i] = l; } return ls[0]; } int length(ListNode* p) { if (p == NULL) return 0; int n = 0; while (p != NULL) { n++; p = p->next; } return n; } List mergeList(List l1, List l2) { if (l1.len == 0) return l2; if (l2.len == 0) return l1; List r; r.len = l1.len + l2.len; ListNode* p1 = l1.head; ListNode* p2 = l2.head; if (p1->val < p2->val) { r.head = p1; p1 = p1->next; } else { r.head = p2; p2 = p2->next; } ListNode* p = r.head; while (p1 != NULL && p2 != NULL) { if (p1->val < p2->val) { p->next = p1; p1 = p1->next; } else { p->next = p2; p2 = p2->next; } p = p->next; } if (p1 != NULL) { p->next = p1; } if (p2 != NULL) { p->next = p2; } return r; } };