标签:algorithm leetcode linked list sorted lists merge
Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.
一开始我没有采用分治法,解题思路是:首先比较每条链表的第一个元素,找出最小的那个,插入新链表并从原链表删除,如此反复直至所有的链表都为空链表。基于这个愚蠢的解题思路,我的C++代码实现如下:
ListNode *mergeKLists(vector<ListNode *> &lists) {
ListNode *dummyHead = new ListNode(0);
ListNode *tail = dummyHead;
int leftLists = lists.size();
for (int i = 0; i < leftLists; i++)
if (!lists[i])
lists[i--] = lists[--leftLists];
while (leftLists) {
int curMinIdx = 0;
for (int i = 1; i < leftLists; i++)
if (lists[i]->val < lists[curMinIdx]->val)
curMinIdx = i;
tail->next = lists[curMinIdx];
tail = lists[curMinIdx];
lists[curMinIdx] = lists[curMinIdx]->next ? lists[curMinIdx]->next : lists[--leftLists];
}
return dummyHead->next;
}
毫无疑问,我得到了“Time Limit Exceeded”,这种解法对于每一个元素都查找了所有的链表,这个复杂度是非常高的。以后一定要避免这样的解法!
然后,我采用了分治法,每次合并两条链表,采用堆排序算法来实现:
class Solution {
public:
ListNode *mergeKLists(vector<ListNode *> &lists) {
int leftLists = lists.size();
while (leftLists > 1) {
for (int i = 0; i < (leftLists >> 1); ++i)
lists[i] = merge2Lists(lists[i], lists[leftLists - 1 - i]);
leftLists = (leftLists + 1) >> 1;
}
return lists.empty() ? nullptr : lists[0];
}
ListNode *merge2Lists(ListNode *h1, ListNode *h2) {
ListNode *dummyHead = new ListNode(0);
ListNode *tail = dummyHead, *cur[2] = {h1, h2};
while (cur[0] && cur[1]) {
int idx = (cur[0]->val >= cur[1]->val);
tail->next = cur[idx];
tail = cur[idx];
cur[idx] = cur[idx]->next;
}
if (cur[0]) tail->next = cur[0];
if (cur[1]) tail->next = cur[1];
return dummyHead->next;
}
};
后者的时间性能表现如下图所示,可以看到这种做法在C++里面的时间性能并不好,希望以后发掘更好更快的算法。
LeetCode[Linked List]: Merge k Sorted Lists
标签:algorithm leetcode linked list sorted lists merge
原文地址:http://blog.csdn.net/chfe007/article/details/43450705