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

思路:这题最容易想到的是,(假设有k个链表)链表1、2合并,然后其结果12和3合并,以此类推,最后是123--k-1和k合并。至于两链表合并的过程见merge two sorted lists的分析。复杂度的分析见JustDoIT的博客。算法复杂度:假设每个链表的平均长度是n,则1、2合并,遍历2n个节点;12结果和3合并,遍历3n个节点;....123...k-1的结果和k合并,遍历kn个节点,总共遍历n(2+3+4+....k)=n*(k^2+k-2)/2,因此时间复杂度是O(n*(k^2+k-2)/2)=O(nk^2)。     其次,可以想到用分治的思想,两两合并直至最后。

针对方法一,

 class Solution {
public:
//用向量存储链表
ListNode *mergeKLists(vector<ListNode *> &lists)
{
if(lists.size()==) return NULL;
ListNode *res=lists[]; //取出第一个链表
for(int i=;i<lists.size();i++) //反复调用
res=mergeTwoList(res,lists[i]); return res;
} //归并排序
ListNode *mergeTwoList(ListNode *head1,ListNode *head2)
{
ListNode node(); //创建头结点的前置结点
ListNode *res=&node;
while(head1&&head2)
{
if(head1->val<=head2->val)
{
res->next=head1;
head1=head1->next;
}
else
{
res->next=head2;
head2=head2->next;
}
res=res->next;
} if(head1)
res->next=head1;
else if(head2)
res->next=head2; return node.next;
}
};

针对方法二:比较难想的是,两两合并时,链表的选取。

 /**
* 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)
{
int len=lists.size();
if(len==)
return NULL; while(len>)
{
int k=(len+)>>; for(int i=;i<len/;++i)
{
lists[i]=mergeTwoLists(lists[i],lists[i+k]);
}
len=k;
}
return lists[];
} ListNode *mergeTwoLists(ListNode *head1,ListNode *head2)
{
ListNode *nList=new ListNode(-);
nList->next=head1;
ListNode *pre=nList; while(head1&&head2)
{
if(head1->val >head2->val)
{
pre->next=head2;
head2=head2->next;
}
else
{
pre->next=head1;
head1=head1->next;
}
pre=pre->next;
} if(head1)
{
pre->next=head1;
}
else
pre->next=head2; return nList->next;
}
};

还有一种方法是最小堆的方法,维护一个大小为k的最小堆,初始化堆中的元素为每个链表的表头,它们会自动排好序,然后取出其中的最小元素介入新的链表中,然后,将最小元素的后继压入堆中,下次再从堆中选取最小的元素。元素加入堆中的复杂度为O(longk),总共有kn个元素加入堆中,因此,复杂度也和算法2一样是O(nklogk)。具体代码如下:

 class Solution
{
private:
struct cmp
{
bool operator()(const ListNode *a,const ListNode *b)
{
return a->val >b->val;
}
}
public:
//用向量存储链表
ListNode *mergeKLists(vector<ListNode *> &lists)
{
int n=lists.size();
if (n==) return NULL; ListNode node();
ListNode *res=&node; priority_queue<ListNode*,vector<ListNode*>,cmp> que; for(int i=;i<n;i++)
{
if(lists[i])
que.push(list[i]);
} while(! que.empty())
{
ListNode *p=que.top();
que.pop();
res->next=p;
res=p; if(p->next)
que.push(p->next);
} return node.next;
}
}

此篇中,有很多分析过程都是来自JustDoITGrandyang的博客。

[Leetcode] Merge k sorted lists 合并k个已排序的链表的更多相关文章

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

    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 合并K个升序链表

    作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 个人公众号:负雪明烛 本文关键词:合并,链表,单链表,题解,leetcode, 力扣,Py ...

  4. Leetcode23--->Merge K sorted Lists(合并k个排序的单链表)

    题目: 合并k个排序将k个已排序的链表合并为一个排好序的链表,并分析其时间复杂度 . 解题思路: 类似于归并排序的思想,lists中存放的是多个单链表,将lists的头和尾两个链表合并,放在头,头向后 ...

  5. 【LeetCode每天一题】 Merge k Sorted Lists(合并K个有序链表)

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

  6. [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 ...

  7. 023 Merge k Sorted Lists 合并K个有序链表

    合并K个有序链表,并且作为一个有序链表的形式返回.分析并描述它的复杂度. 详见:https://leetcode.com/problems/merge-k-sorted-lists/descripti ...

  8. [Leetcode] Merge two sorted lists 合并两已排序的链表

    Merge two sorted linked lists and return it as a new list. The new list should be made by splicing t ...

  9. [LeetCode] 21. Merge Two Sorted Lists 合并有序链表

    Merge two sorted linked lists and return it as a new list. The new list should be made by splicing t ...

随机推荐

  1. maven-认识

    1.认识maven maven是强大的项目构建工具,也是依赖管理工具 使用maven前提是安装JDK maven非常重要配置文件:setting.xml 3.maven工程 maven工程的约束: 主 ...

  2. 【tp5.1】微信公众号授权登录及获取信息录入数据库

    微信公众号开发文档链接:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1445241432 微信公众号授权登录分为两种: 1.以 ...

  3. Leecode刷题之旅-C语言/python-66加一

    /* * @lc app=leetcode.cn id=66 lang=c * * [66] 加一 * * https://leetcode-cn.com/problems/plus-one/desc ...

  4. Leecode刷题之旅-C语言/python-14.最长公共前缀

    /* * @lc app=leetcode.cn id=14 lang=c * * [14] 最长公共前缀 * * https://leetcode-cn.com/problems/longest-c ...

  5. 解决MySQL server has gone away问题的两种有效办法

    最近做网站有一个站要用到WEB网页采集器功能,当一个PHP脚本在请求URL的时候,可能这个被请求的网页非常慢慢,超过了mysql的 wait-timeout时间,然后当网页内容被抓回来后,准备插入到M ...

  6. 003---socket介绍

    socket介绍 什么是socket? socket是应用层与tcp/ip协议族通信的中间软件抽象层,它是一组接口.在设计模式中.其实就是一个门面模式.我们无需深入理解tcp/udp协议,socket ...

  7. Element-ui学习使用

    这是我使用Element-ui的布局,排布的一个界面,原本我是使用WinfowsForm来做的一个摄像头注册以及查询的小工具,目前我关注前后端的开发,所以就想着能不能把这么个小工具,我用前后端的形式开 ...

  8. DSP28335的XINTF操作SRAM实验

    1. 本次使用三兄弟的XDS28335开发板,研究一下XINTF操作SRAM的代码.哈弗结构,奇怪,DSP28335是哈弗结构,那么数据和程序空间应该独立的,为啥书上说采用统一的寻址方式?估计只是读写 ...

  9. 激活Windows Server 2008R2

    1. 用管理员身份运行mini-KMS_Activator_v1.053_ENG 2. 点击倒数第二个菜单Activation Windows VL 选择数字1 下一步选择Y 不管后面报不报错 3. ...

  10. android get cpu rate

    public static int getProcessCpuRate() { try { RandomAccessFile reader = new RandomAccessFile("/ ...