题目描述
合并 k 个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。
示例
输入: [ 1->4->5, 1->3->4, 2->6 ] 输出: 1->1->2->3->4->4->5->6
思路
分治法
实现
struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};
ListNode* mergeTwoList(ListNode* left, ListNode* right)
{
if (left == nullptr)
{
return right;
}
if (right == nullptr)
{
return left;
}
ListNode* head;
if (left->val <= right->val)
{
head = left;
head->next = mergeTwoList(left->next, right);
} else {
head = right;
head->next = mergeTwoList(left, right->next);
}
return head;
}
ListNode* mergeKLists(vector<ListNode*>& lists) {
if (lists.size() == 0)
{
return nullptr;
} else if (lists.size() == 1)
{
return lists[0];
} else if (lists.size() == 2)
{
return mergeTwoList(lists[0], lists[1]);
}
int mid = lists.size() / 2;
vector<ListNode*> left(mid);
vector<ListNode*> right(lists.size() - mid);
for (int i = 0; i < mid; i++)
{
left[i] = lists[i];
}
for (int i = mid, j = 0; i < lists.size(); i++, j++)
{
right[j] = lists[i];
}
return mergeTwoList(mergeKLists(left), mergeKLists(right));
}
思路2
利用有限队列建立小顶堆,每次将堆顶元素放在结果链表的尾部。
实现
struct cmp1{
bool operator ()(ListNode* l1, ListNode* l2) {
return l1->val > l2->val;
}
};
ListNode* mergeKLists(vector<ListNode*>& lists) {
priority_queue<ListNode*, vector<ListNode*>, cmp1> que;
for (int i = 0; i < lists.size(); i++)
{
if (lists[i] == nullptr)
{
continue;
}
que.push(lists[i]);
}
ListNode* dummy = new ListNode(-1);
ListNode* curNode = dummy;
while (!que.empty())
{
ListNode* nextNode = que.top();
curNode->next = nextNode;
curNode = nextNode;
que.pop();
if (nextNode->next != nullptr)
{
que.push(nextNode->next);
}
}
return dummy->next;
}