Merge k sorted linked lists and return it as one sorted list.

题意:把k个已经排好序的链表整合到一个链表中,并且这个链表是排了序的。

题解:这是一道经典好题,值得仔细一说。

有两种方法,假设每个链表的平均长度是n,那么这两种方法的时间复杂度都是O(nklogk)。

方法一

基本思路是:把k个链表开头的值排个序,每次取最小的一个值放到答案链表中,这次取完之后更新这个值为它后面的一个值。接着这么取一直到全部取完。那么每次更新之后怎么对当前这k个值重新排序以便知道当前最小的是谁呢?用优先队列(或者堆)来维护这k个值就好啦!

由于每个值都要取一次,一共取nk次。每次更新优先队列要logk的复杂度。所以总时间复杂度为O(nklogk);空间复杂度为优先队列所占空间,为O(k)。

/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution
{
public:
struct cmp
{
bool operator() (const ListNode* a,const ListNode* b)
{
return a->val > b->val;
}
};
ListNode* mergeKLists(vector<ListNode*>& lists)
{
priority_queue<ListNode*, vector<ListNode*>, cmp>pq;
for(auto i:lists)
{
if(i) //这句判断很有必要,不能把空的加入队列。比如这组数据:[[],[]]
{
pq.push(i);
}
}
if(pq.empty())
{
return nullptr;
}
ListNode* ans = pq.top();
pq.pop();
ListNode* tail = ans;
if(tail->next)
{
pq.push(tail->next);
}
while(!pq.empty())
{
tail->next = pq.top();
tail = tail->next;
pq.pop();
if(tail->next)
{
pq.push(tail->next);
}
}
return ans;
}
};

方法二:

和方法一的思路不同:考虑分治的思想来解这个题(类似归并排序的思路)。把这些链表分成两半,如果每一半都合并好了,那么我就最后把这两个合并了就行了。这就是分治法的核心思想。

但是这道题由于存的都是指针,就具有了更大的操作灵活性,可以不用递归来实现分治。就是先两两合并后在两两合并。。。一直下去直到最后成了一个。(相当于分治算法的那棵二叉树从底向上走了)。

第一次两两合并是进行了k/2次,每次处理2n个值。

第二次两两合并是进行了k/4次,每次处理4n个值。

。。。

最后一次两两合并是进行了k/(2^logk)次,每次处理2^logK*N个值。

所以时间复杂度:

O((2N) * (K / 2) + (4N) * (K / 4) + (8N) * (K / 8) + .............. + (2^logK*N) * (K / (2 ^logK)) )=O( logK*KN)

空间复杂度是O(1)。

/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *mergeKLists(vector<ListNode *> &lists) {
if(lists.empty()){
return nullptr;
}
while(lists.size() > ){
lists.push_back(mergeTwoLists(lists[], lists[]));
lists.erase(lists.begin());
lists.erase(lists.begin());
}
return lists.front();
}
ListNode *mergeTwoLists(ListNode *l1, ListNode *l2) {
if(l1 == nullptr){
return l2;
}
if(l2 == nullptr){
return l1;
}
if(l1->val <= l2->val){
l1->next = mergeTwoLists(l1->next, l2);
return l1;
}
else{
l2->next = mergeTwoLists(l1, l2->next);
return l2;
}
}
};

leetcode 23. Merge k Sorted Lists(堆||分治法)的更多相关文章

  1. 蜗牛慢慢爬 LeetCode 23. Merge k Sorted Lists [Difficulty: Hard]

    题目 Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity ...

  2. [LeetCode] 23. Merge k Sorted Lists 合并k个有序链表

    Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. E ...

  3. [LeetCode] 23. Merge k Sorted Lists ☆☆☆☆☆

    转载:https://leetcode.windliang.cc/leetCode-23-Merge-k-Sorted-Lists.html 描述 Merge k sorted linked list ...

  4. LeetCode 23 Merge k Sorted Lists(合并k个有序链表)

    题目链接: https://leetcode.com/problems/merge-k-sorted-lists/?tab=Description Problem: 给出k个有序的list, 将其进行 ...

  5. [LeetCode] 23. Merge k Sorted Lists ☆☆

    Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. 解 ...

  6. [leetcode 23]Merge k Sorted Lists

    1 题目 Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexi ...

  7. [leetcode]23. Merge k Sorted Lists归并k个有序链表

    Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. I ...

  8. [LeetCode]23. Merge k Sorted Lists合并K个排序链表

    Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. E ...

  9. Java [leetcode 23]Merge k Sorted Lists

    题目描述: Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complex ...

随机推荐

  1. 查看本机外网ip地址

    DOS下是无法查看外网IP的,只能获取本机内网IP地址   外网IP只能通过专门的测IP网站 http://www.ip138.com/ip2city.asp

  2. Cocos2d-x粒子系统

    CCparticleSystem类封装实现对粒子的控制与调度,当中操作包含有: 1.产生粒子 2.更新粒子状态 3.回收无效的粒子 CCparticleSystem派生出CCParticleSyste ...

  3. Android-Animations介绍

    一.Animations介绍 Animations是一个实现android UI界面动画效果的API,Animations提供了一系列的动画效果,可以进行旋转.缩放.淡入淡出等,这些效果可以应用在绝大 ...

  4. Spring配置错误记录

    很多其它Spring问题因为发生时未记录而遗忘了~~~~~~~ 如今动动手 解决方式因为不是源头分析因而仅供參考.! ! 严重: Exception sending context destroyed ...

  5. JQuery如何获取按键的unicode编码?

    $("selector").keyup(function(xxx){ var myEvent = xxx; var code = myEvent.keyCode; alert(co ...

  6. ejabberd日志分析客户端登录流程

    通过ejabberd的日志,整理了下客户端登录流程. 1. 通过TCP连接5222端口的流程: (1) 客户端向服务器发送stream流 <stream:stream to="nba. ...

  7. Android使用ViewPager实现无限循环滑动及轮播(附源代码)

    MainActivity例如以下: package cc.ww; import java.util.ArrayList; import android.app.Activity; import and ...

  8. json (js对象标记)

    基础 JSON: JavaScript Object Notation (JavaScript对象表示法) 网络媒体类型是 application/json,文件名扩展是 .json JSON 独立于 ...

  9. Linux安装mariadb详细步骤

    1.安装mariadb yum和源码编译安装的区别? 1.路径区别-yum安装的软件是他自定义的,源码安装的软件./configure --preifx=软件安装的绝对路径 2.yum仓库的软件,版本 ...

  10. ABAP 关键字(1)

    1.定义DATA ,TYPES TYPES关键字用于创建自定义数据类型,就像JAVA里面创建类一样,用TYPES创建的数据类型可以被其它变量引用(类似于实例化对象),而本身不能直接引用或者赋值. DA ...