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. iWebShop产品功能技术优势有什么?

    iwebshop基于iweb si 框架开发,在获得iweb si 技术平台支持的条件下,iwebshop可以轻松满足用户量级百万至千万级的大型电子商务网站的性能要求.站点的集群与分布式技术(分布式计 ...

  2. ubuntu 14.04离线安装docker和docker compose

    准备安装包 1.下载docker docker支持以下版本的ubuntu系统Artful 17.10 (Docker CE 17.11 Edge)Zesty 17.04Xenial 16.04 (LT ...

  3. 【JDBC】一、JDBC连接数据库

    package com.jdbc; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLExce ...

  4. git的关于测试的相关的内容

    今天,我们来讲一下git的分支的一些内容,在以前的时候,我一直都以为,对于一个项目,这个时候,我们把这个项目叫做项目a项目,这个a项目有master,staging,以及我自己的分支xxx,当我想上测 ...

  5. WPF中的命令与命令绑定(一)

    原文:WPF中的命令与命令绑定(一)   WPF中的命令与命令绑定(一)                                           周银辉说到用户输入,可能我们更多地会联想到 ...

  6. android开源项目之OTTO事件总线(二)官方demo解说

    官方demo见  https://github.com/square/otto 注意自己该编译版本为2.3以上,默认的1.6不支持match_parent属性,导致布局文件出错. 另外需要手动添加an ...

  7. (原)一段看似美丽的for循环,背后又隐藏着什么

    之前很长一段时间,潜心修炼汇编,专门装了一个dos7,慢慢玩到win32汇编,再到linux的AT&A汇编,尝试写mbr的时候期间好几次把centos弄的开不了机,又莫名其妙的修好了,如今最大 ...

  8. Ubuntu 安装Google浏览器

    Ubuntu自带的浏览器是火狐浏览器,使用的时候多多少少有些不方便,这里安装Googel浏览器. 下载 可以到 Ubuntu chrome去下载安装包. 安装 首先到下载的根目录 cd ~/Downl ...

  9. 修改有数据oracle字段类型 从number转为varchar

    --修改有数据oracle字段类型 从number转为varchar--例:修改ta_sp_org_invoice表中RESCUE_PHONE字段类型,从number转为varchar --step1 ...

  10. Spring实战第四章学习笔记————面向切面的Spring

    Spring实战第四章学习笔记----面向切面的Spring 什么是面向切面的编程 我们把影响应用多处的功能描述为横切关注点.比如安全就是一个横切关注点,应用中许多方法都会涉及安全规则.而切面可以帮我 ...