文章目录
- 题目解析
- 题目链接
- 题目解析
- 算法讲解
- 暴力解法
- 利用优先级队列进行优化
- 代码解析
题目解析
题目链接
首先先把题目连接给大家奉上题目链接
题目解析
严格来说这个题目是非常容易理解的相信大家有了合并两个升序链表来理解这个题目就会非常容易理解了。这个题目的意思就是现在有k个升序链表要求你将这k个升序链表进行合并合并成为一个升序链表。
算法讲解
暴力解法
首先看到一个算法题目我们依然是分为暴力和优化两个步骤看到这个题目有什么暴力解法呢?这里我门可以把当时两两链表合并这个题目的思想运用过来我们合并两个链表的时候是用两个指针那么我们合并多个链表的时候也可以两两合并啊。
比如这里的这个例子如下图
那么这样子的话我们的时间复杂度如何呢?
我们假设每个链表的节点个数为n总共有m个链表那么每一次都需要两两比对,并且每一次新的链表长度都会增加,因此最终的时间复杂度是O(mn^2)这个时间复杂度是很可怕的,因为如果m和n的数字比较接近的话那么时间复杂度就直逼三次方了。因此需要优化
利用优先级队列进行优化
利用优先级队列进行优化,我们可以将这些链表的头节点放入一个优先级队列中之后每当出去一个节点就将出去的这个节点的next节点放入优先级队列中。
代码解析
class Solution {
public:
struct cmp
{
bool operator()(ListNode* n1,ListNode* n2) {
return n1->val > n2->val;
}
};
ListNode* mergeKLists(vector<ListNode*>& lists) {
priority_queue<ListNode*, vector<ListNode*>, cmp>pr;
for (auto l : lists) {
if(l)pr.push(l);
}
ListNode* ret = new ListNode(0);
ListNode* per = ret;
while (!pr.empty()) {
ListNode* ne = pr.top();
pr.pop();
if (ne->next)pr.push(ne->next);
per->next = ne;
per = ne;
}
per=ret->next;
delete(ret);
return per;
}
};
那么我们看一下这个代码首先就是创建一个优先级队列,之后将每个链表的头节点放入堆中
priority_queue<ListNode*, vector<ListNode*>, cmp>pr;
for (auto l : lists) {
if(l)pr.push(l);
}
当完成上面的第一步后我们就要开始下一步从堆中出去并且当出去的这个节点的下一个节点不为空时就把他的next放入堆中
while (!pr.empty()) {
ListNode* ne = pr.top();
pr.pop();
if (ne->next)pr.push(ne->next);
per->next = ne;
per = ne;
}