一、前言
分类:Divide and Conquer。
问题来源LeetCode 23 难度:困难。
问题链接:https://leetcode-cn.com/problems/merge-k-sorted-lists/
二、题目
合并 k 个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。
示例1:
输入:
[
1->4->5,
1->3->4,
2->6
]
输出: 1->1->2->3->4->4->5->6
三、思路
这里提供两种解决方法
方法一:分治合并
方法二:优先队列合并
四、编码实现
//==========================================================================
/*
* @file : 023_MergeKLists.h
* @label : Divide and Conquer
* @blogs : https://blog.csdn.net/nie2314550441/article/details/107424030
* @author : niebingyu
* @date : 2020/07/16
* @title : 23.合并K个排序链表
* @purpose : 合并 k 个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。
*
* 示例:
* 输入:
* [
* 1->4->5,
* 1->3->4,
* 2->6
* ]
* 输出: 1->1->2->3->4->4->5->6
*
*
* 来源:力扣(LeetCode)
* 难度:困难
* 链接:https://leetcode-cn.com/problems/merge-k-sorted-lists/
*/
//==========================================================================
#pragma once
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
#include <assert.h>
using namespace std;
#define NAMESPACE_MERGEKLISTS namespace NAME_MERGEKLISTS {
#define NAMESPACE_MERGEKLISTSEND }
NAMESPACE_MERGEKLISTS
struct ListNode
{
int val;
ListNode* next;
ListNode(int x=0, ListNode * nt = NULL) : val(x), next(nt) {}
};
// 方法一,逐个合并
class Solution_1
{
public:
ListNode* mergeTwoLists(ListNode*a, ListNode*b)
{
if (!a) return b;
if (!b) return a;
ListNode *dummyHead = new ListNode(0);
ListNode *cur = dummyHead;
ListNode *ap = a, *bp = b;
while (ap && bp)
{
if (ap->val > bp->val)
{
cur->next = bp;
bp = bp->next;
}
else
{
cur->next = ap;
ap = ap->next;
}
cur = cur->next;
}
cur->next = ap ? ap : bp;
return dummyHead->next;
}
ListNode* merge(vector<ListNode*> &lists, int l, int r)
{
if (l>r) return NULL;
if (l==r) return lists[l];
int mid = l + (r-l)/2;
return mergeTwoLists(merge(lists, l, mid), merge(lists, mid+1, r));
}
ListNode* mergeKLists(vector<ListNode*>& lists)
{
return merge(lists, 0, lists.size()-1);
}
};
// 方法二,优先队列合并
class Solution_2
{
public:
struct Status
{
int val;
ListNode *ptr;
bool operator < (const Status &rhs) const
{
return val > rhs.val;
}
};
priority_queue <Status> q;
ListNode* mergeKLists(vector<ListNode*>& lists)
{
for (auto node: lists)
{
if (node) q.push({node->val, node});
}
ListNode head;
ListNode *tail = &head;
while (!q.empty())
{
auto f = q.top();
q.pop();
tail->next = f.ptr;
tail = tail->next;
if (f.ptr->next)
q.push({f.ptr->next->val, f.ptr->next});
}
return head.next;
}
};
以下为测试代码//
// 测试 用例 START
void test(const char* testName, vector<ListNode*>& lists, vector<int> expect)
{
Solution_1 s;
ListNode* ret = s.mergeKLists(lists);
vector<int> result;
while (ret)
{
result.push_back(ret->val);
ret = ret->next;
}
if (result == expect)
cout << testName << ", solution passed." << endl;
else
cout << testName << ", solution failed. " << endl;
}
// 测试用例
void Test1()
{
ListNode* hd1_5 = new ListNode(5);
ListNode* hd1_4 = new ListNode(4, hd1_5);
ListNode* hd1 = new ListNode(1, hd1_4);
ListNode* hd2_4 = new ListNode(4);
ListNode* hd2_3 = new ListNode(3, hd2_4);
ListNode* hd2 = new ListNode(1, hd2_3);
ListNode* hd3_6 = new ListNode(6);
ListNode* hd3 = new ListNode(2, hd3_6);
// 只是测试用,懒得释放了
vector<ListNode*> lists = { hd1, hd2, hd3 };
vector<int> expect = { 1, 1, 2, 3, 4, 4, 5, 6};
test("Test1()", lists, expect);
}
NAMESPACE_MERGEKLISTSEND
// 测试 用例 END
//
void MergeKLists_Test()
{
cout << "------ start 23.合并K个排序链表 ------" << endl;
NAME_MERGEKLISTS::Test1();
cout << "------ end 23.合并K个排序链表 ------" << endl;
}
执行结果: