题目描述
Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.
Example:
Input:
[
1->4->5,
1->3->4,
2->6
]
Output: 1->1->2->3->4->4->5->6
解题代码
class Solution {
public:
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
if (l1 == nullptr)
return l2;
if (l2 == nullptr)
return l1;
ListNode * head, *current;
if (l1->val > l2->val) {
head = new ListNode(l2->val);
l2 = l2->next;
}
else {
head = new ListNode(l1->val);
l1 = l1->next;
}
current = head;
while (l1 != nullptr && l2 != nullptr)
{
if (l1->val > l2->val) {
current->next = new ListNode(l2->val);
l2 = l2->next;
}
else {
current->next = new ListNode(l1->val);
l1 = l1->next;
}
current = current->next;
}
ListNode * temp = l1 == nullptr ? l2 : l1;
while (temp != nullptr)
{
current->next = new ListNode(temp->val);
temp = temp->next;
current = current->next;
}
return head;
}
ListNode * mergeSubLists(vector<ListNode*> & lists, int start, int end) {
if (start > end)
return nullptr;
if (start == end)
return lists[start];
int num = (start + end) / 2;
ListNode * first = mergeSubLists(lists, start, num);
ListNode * second = mergeSubLists(lists, num + 1,end);
return mergeTwoLists(first, second);
}
ListNode* mergeKLists(vector<ListNode*>& lists) {
if (lists.size() == 0)
return nullptr;
int num = lists.size() - 1;
ListNode * first = mergeSubLists(lists, 0, num / 2);
ListNode * second = mergeSubLists(lists, num / 2 + 1, num);
return mergeTwoLists(first, second);
}
};
解题思路
- 将k个链表进行合并,每个链表使用一个指针,将k个元素进行比较得到最小值,这样子的时间复杂度是O(NK),N为元素个数,K为链表个数。为了减少比较次数,可以使用一个优先队列,复杂度为O(NlogK)(每次加一个新的元素到队列中,取出最小值,这个花费的时间是logK)。
- 使用归并排序的方法达到同样的复杂度。这也是上面代码使用的方法。不过上面的代码空间复杂度不好,mergeTwoLists中每次都创建了新的空间,并没有删除旧的空间。所以可以将传入的两个链表中的一个为主,另一个插入前一个并及时删除节点。(如果原始的链表不能删除,那可以在开始时复制一遍链表,或者在调用mergeTwoLists函数前判断是否是原始链表,是则不能合并后删除,但可能会出现一个链表是可以删除,一个是原始链表不可以删除的情况,在这种角度看的话使用1的优先队列好像更容易些)