来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/merge-k-sorted-lists

题目描述

给你一个链表数组,每个链表都已经按升序排列。

请你将所有链表合并到一个升序链表中,返回合并后的链表。

示例 1:

输入:lists = [[1,4,5],[1,3,4],[2,6]]
输出:[1,1,2,3,4,4,5,6]
解释:链表数组如下:
[
1->4->5,
1->3->4,
2->6
]
将它们合并到一个有序链表中得到。
1->1->2->3->4->4->5->6
示例 2:

输入:lists = []
输出:[]
示例 3:

输入:lists = [[]]
输出:[]

提示:

k == lists.length
0 <= k <= 10^4
0 <= lists[i].length <= 500
-10^4 <= lists[i][j] <= 10^4
lists[i] 按 升序 排列
lists[i].length 的总和不超过 10^4

解题思路

使用暴力法,每次取最小的链表头,并且更新链表组的数据。时间复杂度为O(k2n),我们可以维护一个优先队列来代替每次找最小值的过程,这样时间复杂度就可以缩短为O(knlogk)。

同样,我们使用分冶的思路,将链表每次两两合并,由于单次合并的时间复杂度为O(n),那么时间复杂度也可以达到O(knlogk)。

代码展示

/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* mergeKLists(vector<ListNode*>& lists) {
ListNode *pHead = new ListNode(-1);
ListNode *pCur = pHead;
int iNull = 0;
for(auto iter: lists)
{
if(iter != nullptr)
iNull++;
}
while(iNull)
{
int iMin = INT_MAX;
ListNode* qCur = nullptr;
int iIndex = -1;
for(int i = 0; i < lists.size(); i++)
{
if(lists[i])
{
if(lists[i]->val < iMin)
{
qCur = lists[i];
iIndex = i;
iMin = lists[i]->val;
}
}
}
pCur->next = qCur;
lists[iIndex] = qCur->next;
if(!lists[iIndex])
iNull--;
qCur->next = nullptr;
pCur = qCur;
}
return pHead->next;
}
};

优先队列方法:

/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public: ListNode* mergeKLists(vector<ListNode*>& lists) {
ListNode *pHead = new ListNode(-1);
ListNode *pCur = pHead;
struct cmp
{
bool operator() (ListNode *a, ListNode*b)
{
return a->val > b->val;
}
}; priority_queue<ListNode*, vector<ListNode*>, cmp> pqueue;
for(auto iter: lists)
{
if(iter)
pqueue.push(iter);
}
while(!pqueue.empty())
{
ListNode* qCur = pqueue.top();
pqueue.pop();
pCur->next = qCur;
if(qCur->next)
pqueue.push(qCur->next);
qCur->next = nullptr;
pCur = qCur;
}
return pHead->next;
}
};

分冶方法:

/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* mergeList(ListNode* p, ListNode*q)
{
ListNode *pHead = new ListNode(-1);
ListNode *pCur = pHead;
while(p && q)
{
if(p->val > q->val)
{
pCur->next = q;
q = q->next;
pCur = pCur->next;
}
else
{
pCur->next = p;
p = p->next;
pCur = pCur->next;
}
}
if(p)
pCur->next = p;
if(q)
pCur->next = q;
return pHead->next;
} ListNode* mergeKLists(vector<ListNode*>& lists) {
int iStep = 1;
if(lists.size() == 0)
return nullptr;
while(iStep < lists.size())
{
for(int i = 0; i + iStep < lists.size(); i += 2 * iStep)
{
lists[i] = mergeList(lists[i], lists[i + iStep]);
}
iStep *= 2;
}
return lists[0];
}
};

运行结果

LeetCode-23 合并K个升序链表的更多相关文章

  1. LeetCode 23. 合并K个排序链表(Merge Two Sorted Lists)

    23. 合并K个排序链表 23. Merge k Sorted Lists 题目描述 合并 k 个排序链表,返回合并后的排序链表.请分析和描述算法的复杂度. LeetCode23. Merge k S ...

  2. Java实现 LeetCode 23 合并K个排序链表

    23. 合并K个排序链表 合并 k 个排序链表,返回合并后的排序链表.请分析和描述算法的复杂度. 示例: 输入: [ 1->4->5, 1->3->4, 2->6 ] 输 ...

  3. [LeetCode题解]23. 合并K个升序链表 | 分治 + 递归

    方法一:分治 + 递归 解题思路 在21. 合并两个有序链表,我们知道如何合并两个有序链表.而本题是合并 k 个有序链表,可以通过大问题拆分成小问题解决,即把 k 个链表,拆分成 k/2 个链表组,俩 ...

  4. [LeetCode]23. 合并K个排序链表(优先队列;分治待做)

    题目 合并 k 个排序链表,返回合并后的排序链表.请分析和描述算法的复杂度. 示例: 输入: [   1->4->5,   1->3->4,   2->6 ] 输出: 1 ...

  5. [LeetCode] 23. 合并K个排序链表

    题目链接: https://leetcode-cn.com/problems/merge-k-sorted-lists/ 题目描述: 合并 k 个排序链表,返回合并后的排序链表.请分析和描述算法的复杂 ...

  6. leetcode 23. 合并K个排序链表 JAVA

    题目: 合并 k 个排序链表,返回合并后的排序链表.请分析和描述算法的复杂度. 示例: 输入: [   1->4->5,   1->3->4,   2->6 ] 输出: ...

  7. LeetCode 23. 合并K个排序链表(Merge k Sorted Lists)

    题目描述 合并 k 个排序链表,返回合并后的排序链表.请分析和描述算法的复杂度. 示例: 输入: [   1->4->5,   1->3->4,   2->6 ] 输出: ...

  8. 【每日一题】【小根堆&边出队边入队后续节点&注意判空】23. 合并K个升序链表-211128/220213

    给你一个链表数组,每个链表都已经按升序排列. 请你将所有链表合并到一个升序链表中,返回合并后的链表. 答案1(参数是数组): /** * Definition for singly-linked li ...

  9. LeetCode 23 ——合并 K 个排序链表

    1. 题目 2. 解答 2.1. 方法一 在 合并两个有序链表 的基础上,我们很容易想到第一种解法,首先我们将第一个链表和第二个链表合并成一个新的链表,然后再往后依次合并接下来的每个链表即可. 假设每 ...

  10. 浅谈归并排序:合并 K 个升序链表的归并解法

    在面试中遇到了这道题:如何实现多个升序链表的合并.这是 LeetCode 上的一道原题,题目具体如下: 用归并实现合并 K 个升序链表 LeetCode 23. 合并K个升序链表 给你一个链表数组,每 ...

随机推荐

  1. JavaScript:操作符:赋值运算符和空赋值(??=)

    =号是赋值运算,即返回符号右边的结果,同时将结果赋值给符号左边的变量,考虑下面代码的运行结果: 赋值运算b = 1 + 1,做了两件事,先返回符号右边的结果,即2,这个2将参与a = 1 + 2的计算 ...

  2. [图像处理] YUV图像处理入门4

    9 yuv420图像截取 本程序中的函数主要是对YUV420P视频数据流的第一帧图像进行截取.类似opencv中的rect函数,函数的代码如下所示: /** * @file 9 yuv_clip.cp ...

  3. 2_cookie、session、token、sign

    一.关于cookie.session.token.sign 借鉴链接:https://juejin.cn/post/7147913027785293855

  4. 为什么网络I/O会被阻塞?

    摘要:I/O 其实就是 input 和 output 的缩写,即输入/输出. 本文分享自华为云社区<为啥网络IO会被阻塞呢>,作者: 龙哥手记. 我们应该都知道 socket(套接字),你 ...

  5. 为测试管理正名,华为云CodeArts TestPlan的守护之道

    摘要:华为云CodeArts TestPlan既有公有云版本,也有下沉到私有云的版本. 本文分享自华为云社区<为测试管理正名,华为云CodeArts TestPlan的守护之道>,作者:云 ...

  6. 《机器人SLAM导航核心技术与实战》第1季:第4章_机器人传感器

    <机器人SLAM导航核心技术与实战>第1季:第4章_机器人传感器 视频讲解 [第1季]4.第4章_机器人传感器-视频讲解 [第1季]4.1.第4章_机器人传感器_惯性测量单元-视频讲解 [ ...

  7. margin-left:auto的妙用

    问题描述 如上图所示,我们需要将上述三个标签右对齐,就像上图是要达到的效果,一般采用的方法是对每个标签设置margin-left这样就需要设置三个值. 当文字变长或者变成英文的时候又需要重新设置,否则 ...

  8. 笔记本USB接口案例_分析-笔记本USB接口案例_实现

    笔记本USB接口案例_分析 笔记本电脑(laptop)通常具备使用USB设备的功能.在生产时,笔记本都预留了可以插入USB设备的USB接口, 但具体是什么USB设备,笔记本厂商并不关心,只要符合USB ...

  9. chatGPT 桌面版安装教程

    概述 标题党了,首先声明 ChatGPT 官方没有桌面版,目前市面上很多的桌面应用也在是浏览器上包了一层,而且大多做的比较粗糙,不太好用,所以都不太推荐. 作为一名骨灰级的程序员,ChatGPT 的重 ...

  10. 分布式事务 | 使用DTM 的Saga 模式

    DTM 简介 前面章节提及的MassTransit.dotnetcore/CAP都提供了分布式事务的处理能力,但也仅局限于Saga和本地消息表模式的实现.那有没有一个独立的分布式事务解决方案,涵盖多种 ...