题目链接

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

合并k个有序的链表,我们假设每个链表的平均长度是n。这一题需要用到合并两个有序的链表子过程

算法1

最傻的做法就是先1、2合并,12结果和3合并,123结果和4合并,…,123..k-1结果和k合并,我们计算一下复杂度。

1、2合并,遍历2n个节点

12结果和3合并,遍历3n个节点

123结果和4合并,遍历4n个节点

123..k-1结果和k合并,遍历kn个节点

总共遍历的节点数目为n(2+3+…+k) = n*(k^2+k-2)/2, 因此时间复杂度是O(n*(k^2+k-2)/2) = O(nk^2),代码如下:

/**
* 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.size() == 0)return NULL;
ListNode*res = lists[0];
for(int i = 1; i < lists.size(); i++)
res = merge2list(res, lists[i]);
return res;
} ListNode *merge2list(ListNode *head1, ListNode*head2)
{
ListNode node(0), *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;
}
};

算法2:利用分治的思想把合并k个链表分成两个合并k/2个链表的任务,一直划分,知道任务中只剩一个链表或者两个链表。可以很简单的用递归来实现。因此算法复杂度为T(k) = 2T(k/2) + O(nk),很简单可以推导得到算法复杂度为O(nklogk)

递归的代码就不贴了。下面是非递归的代码非递归的思想是(以四个链表为例):                   本文地址

1、3合并,合并结果放到1的位置

2、4合并,合并结果放到2的位置

再把1、2合并(相当于原来的13 和 24合并)

/**
* 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 n = lists.size();
if(n == 0)return NULL;
while(n >1)
{
int k = (n+1)/2;
for(int i = 0; i < n/2; i++)
lists[i] = merge2list(lists[i], lists[i + k]);
n = k;
}
return lists[0];
} ListNode *merge2list(ListNode *head1, ListNode*head2)
{
ListNode node(0), *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;
}
};

算法3:维护一个k个大小的最小堆,初始化堆中元素为每个链表的头结点,每次从堆中选择最小的元素加入到结果链表,再选择该最小元素所在链表的下一个节点加入到堆中。这样当堆为空时,所有链表的节点都已经加入了结果链表。元素加入堆中的复杂度为O(longk),总共有kn个元素加入堆中,因此,复杂度也和算法2一样是O(nklogk)

/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/ 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 == 0)return NULL;
ListNode node(0), *res = &node;
priority_queue<ListNode*, vector<ListNode*>, cmp> que;
for(int i = 0; i < n; i++)
if(lists[i])
que.push(lists[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;
}
};

【版权声明】转载请注明出处http://www.cnblogs.com/TenosDoIt/p/3673188.html

LeetCode:Merge k Sorted Lists的更多相关文章

  1. LeetCode: Merge k Sorted Lists 解题报告

    Merge k Sorted Lists Merge k sorted linked lists and return it as one sorted list. Analyze and descr ...

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

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

  3. LeetCode——Merge k Sorted Lists

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

  4. leetcode -- Merge k Sorted Lists add code

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

  5. LeetCode Merge k Sorted Lists (链表)

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

  6. [Leetcode] Merge k sorted lists 合并k个已排序的链表

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

  7. Leetcode:Merge k Sorted Lists分析和实现

    题目大意是传入一个链表数组lists,每个链表都由若干个链接的链表结点组成,并且每个链表结点记录一个整数.题目保证传入的链表中的整数按从小到大进行排序. 题目要求我们输出一个新的链表,这个链表中应该包 ...

  8. LeetCode Merge k Sorted Lists 解决报告

    https://oj.leetcode.com/problems/merge-k-sorted-lists/ 归并K已经整理阵列,和分析算法的复杂. 解决报告:无论是不考虑优化,最简单的实现是要重新走 ...

  9. LeetCode —— Merge k Sorted Lists

    /* ** 算法的思路: ** 1.将k个链表的首元素进行建堆 ** 2.从堆中取出最小的元素,放到链表中 ** 3.如果取出元素的有后续的元素,则放入堆中,若没有则转步骤2,直到堆为空 */ #in ...

随机推荐

  1. 获取OpenFileDialog的文件名和文件路径

    得到文件名 string fileName = ofd.SafeFileName; 得到路径 string filePath = System.IO.Path.GetDirectoryName(ofd ...

  2. iOS 应用的生命周期

    为了研究应用的生命周期,在AppDelegate的方法里面加入打印当前的函数名的方法: 如下: 1.运行程序: 输出: 2.按一下home键 3.再点击应用 4.双击Home键,向上滑动应用,杀掉应用 ...

  3. ftp文件上传下载实用命令

    连接 >ftp yourhost >user yourusername >password your password 顺利的话连接成功 >dir ;获取remote目录列表 ...

  4. [Android]从Launcher开始启动App流程源码分析

    以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/5017056.html 从Launcher开始启动App流程源码 ...

  5. IOS开发基础知识--碎片25

    1:使用@protocol实现delegate和datasource模式 #import <UIKit/UIKit.h> @protocol MyViewDataSource,MyView ...

  6. Android—判断当前时间段

    思路:获取当前时间相对于当天的分钟数,然后按照时间顺序依次与时间段后面的时间(转化为分钟数)比较(如8:00-9:00,跟9:00比较). 部分代码: 当前时间 Calendar calendar = ...

  7. rails中的form_for

    1 form_for方法是ActionView::Helpers::FormHelper模块内的方法,所以可以在ActionView的实例中直接调用 2 from_for方法的原型为form_for( ...

  8. Windows操作系统优化(Win7版) - 进阶者系列 - 学习者系列文章

    Windows系统优化是个永恒的话题.在操作系统的打包制作方面更是有得一拼.前面提到的龙帝国社区的XP系统就是一个典型的例子,打包好的系统就已经是经过优化的,使用者无需再使用优化工具进行处理.下面就对 ...

  9. FastDFS+Nginx(单点部署)事例

    FastDFS是由淘宝的余庆先生所开发,是一个轻量级.高性能的开源分布式文件系统,用纯C语言开发,包括文件存储.文件同步.文件访问(上传.下载).存取负载均衡.在线扩容.相同内容只存储一份等功能,适合 ...

  10. SqlServer数据类型

    Character 字符串: 数据类型 描述 存储 char(n) 固定长度的字符串.最多 8,000 个字符. n varchar(n) 可变长度的字符串.最多 8,000 个字符.   varch ...