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; } };