1. 题目
Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.
2. 思路
第一反应是采用败者树的merge模式,但是败者树的数据结构也就在大二时学过,早忘了细节,实现麻烦。模拟了一下,每次merge最小的两个链,但是选链是每次排序后选择的,有一个case是每条链都是一个字符,链很多,于是超时了。起始也可以改进一下将排序改为链表结构的插入排序。更好的是改为Heap结构。没有实施。
改为两路merge的方式,通过递归实现很简单。
3. 代码
耗时: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;
}
};