题意:合并K个有序链表返回合并后的链表
思路:最直观的思路是将第一个和第二个链表合并为一个链表,再将该链表与后一个合并,以此类推。时间复杂度为o(kn),Time Limit Exceeded。
class Solution {
public:
ListNode* merge2Lists(ListNode* l1, ListNode* l2)
{
ListNode* head = NULL;
ListNode* r = NULL;
if (l1 == NULL&&l2 == NULL) return NULL;
if (l1 != NULL&&l2 == NULL) return l1;
if (l1 == NULL&&l2 != NULL) return l2;
if (l1->val<l2->val) {
head = new ListNode(l1->val);
l1 = l1->next;
}
else {
head = new ListNode(l2->val);
l2 = l2->next;
}
r = head;
while (l1 != NULL&&l2 != NULL) {
if (l1->val<l2->val) {
r->next = l1;
l1 = l1->next;
r = r->next;
}
else {
r->next = l2;
l2 = l2->next;
r = r->next;
}
}
if (l1 != NULL&&l2 == NULL)
{
r->next = l1;
}
else if (l1 == NULL&&l2 != NULL)
{
r->next = l2;
}
return head;
}
ListNode* mergeKLists(vector<ListNode*>& lists) {
if (lists.empty()) return NULL;
if (lists.size() == 1) return lists[0];
ListNode* head = lists[0];
for (int i = 1; i < lists.size(); i++)
{
ListNode* cur = lists[i];
head = merge2Lists(head, cur);
}
return head;
}
};
第二种方法是先递归的对链表的前半部分和后半部分进行归并排序,最后再merge。
以下代码顺利AC了,时间复杂度为:O(NlogK)【转载】
class Solution {
public:
ListNode* merge2Lists(ListNode* l1, ListNode* l2)
{
ListNode* head = NULL;
ListNode* r = NULL;
if (l1 == NULL&&l2 == NULL) return NULL;
if (l1 != NULL&&l2 == NULL) return l1;
if (l1 == NULL&&l2 != NULL) return l2;
if (l1->val<l2->val) {
head = new ListNode(l1->val);
l1 = l1->next;
}
else {
head = new ListNode(l2->val);
l2 = l2->next;
}
r = head;
while (l1 != NULL&&l2 != NULL) {
if (l1->val<l2->val) {
r->next = l1;
l1 = l1->next;
r = r->next;
}
else {
r->next = l2;
l2 = l2->next;
r = r->next;
}
}
if (l1 != NULL&&l2 == NULL)
{
r->next = l1;
}
else if (l1 == NULL&&l2 != NULL)
{
r->next = l2;
}
return head;
}
ListNode* mergeKLists(vector<ListNode*>& lists) {
if (lists.empty()) return NULL;
if (lists.size() == 1) return lists[0];
int length = lists.size() ;
int mid = (length - 1)/2 ;
vector<ListNode*> low(lists.begin(),lists.begin()+mid+1);
vector<ListNode*> high(lists.begin()+mid+1,lists.end());
ListNode* l1 = mergeKLists(low);
ListNode* l2 = mergeKLists(high);
return merge2Lists(l1,l2) ;
}
};
第三种方法,将每个链表头结点的值都放在一个最小堆里面,取堆顶元素插入新链表的,然后将取出元素所在链表的下一节点的值放入堆中,再将堆变成最小堆。最小堆相关的知识有些忘记,下一次补充。