题意:

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

分析:

方法1:

利用做过的merge 2 sorted list,将头两个归并,结果再与下一个归并,以此类推,归并完所有。

时间复杂度分析是个小问题, merge 2 sorted list的复杂度是O(n),本以为结果就是O(n * k)。

但是仔细考虑,随着归并不断进行,其中一个链表的长度不断增加,直至O(n * k),所以复杂度应该是O(n * k^2)

代码:

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

方法2:

利用最小堆。将所有链表的第一个节点加入堆,然后每次取出值最小的节点,并将该节点的next节点加入堆中。堆为空后所以节点处理完,归并后链表。

堆的大小为k,所以插入删除取节点复杂度均为O(logk),共对O(nk)个节点进行操作,所以时间复杂度为O(nklogk)。

注:

本题除了算法思想本身,还有对于实现过程还是有需要总结的。

1) STL的priority_queue默认的是最大堆,需要重载比较函数。 

  首先一般来讲priority有三个参数,即

template < class T, class Container = vector<T>,
class Compare = less<typename Container::value_type> > class priority_queue;

可以看出,2、3有缺省值,即表示用vector实现priority_queue,实现的是最大堆。所以可以不写这两个参数。

但是如果要修改比较方式,即第三个参数的话,第二个参数也要给出(以前没用过,真是查文档才知道)。

对于内置类型,如int,可以使用stl的functor如 greater<int>直接修改堆的大小属性,但是自定义节点,如本例的ListNode,需要自己重载。

2)对于传入比较函数,一种方法是重载类的operator <,但是leetcode中ListNode的定义是不能修改的。

  还有就是写一个cmp函数,值得注意的是。funtor作为一个类需要重载其operator(),即对于本题,写为

    struct cmp{
bool operator() (ListNode* l1, ListNode* l2) {
return l1 -> val > l2 -> val;
}
};

另外,priority_queue的第三个参数不能只传函数,必须封装成个functor(类),开始写的时候传函数报错了。

总之这题收货还是不少,不论从算法角度还是语言角度。

代码:

 /**
* 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() (ListNode* l1, ListNode* l2) { //why?!
return l1 -> val > l2 -> val;
}
};
public:
ListNode* mergeKLists(vector<ListNode*>& lists) {
ListNode dummy();
ListNode* head = &dummy;
priority_queue<ListNode*, vector<ListNode*>, cmp> que;
for (int i = ; i < lists.size(); ++i) {
if (lists[i] != nullptr) {
que.push(lists[i]);
}
}
while (!que.empty()) {
ListNode* temp = que.top();
head -> next = temp;
head = head -> next;
que.pop();
if (temp -> next != nullptr) {
que.push(temp->next);
}
}
return dummy.next;
}
};

LeetCode23 Merge k Sorted Lists的更多相关文章

  1. Merge k Sorted Lists

    1. Merge Two Sorted Lists 我们先来看这个 问题: Merge two sorted linked lists and return it as a new list. The ...

  2. 71. Merge k Sorted Lists

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

  3. 【leetcode】Merge k Sorted Lists

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

  4. 【LeetCode练习题】Merge k Sorted Lists

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

  5. [Leetcode][Python]23: Merge k Sorted Lists

    # -*- coding: utf8 -*-'''__author__ = 'dabay.wang@gmail.com' 23: Merge k Sorted Listshttps://oj.leet ...

  6. LeetCode之“链表”:Merge Two Sorted Lists && Merge k Sorted Lists

    1. Merge Two Sorted Lists 题目链接 题目要求:  Merge two sorted linked lists and return it as a new list. The ...

  7. leetcode-algorithms-23 Merge k Sorted Lists

    leetcode-algorithms-23 Merge k Sorted Lists Merge k sorted linked lists and return it as one sorted ...

  8. python 中的堆 (heapq 模块)应用:Merge K Sorted Lists

    堆是计算机科学中一类特殊的数据结构的统称.堆通常是一个可以被看做一棵树的数组对象.在队列中,调度程序反复提取队列中第一个作业并运行,因为实际情况中某些时间较短的任务将等待很长时间才能结束,或者某些不短 ...

  9. 蜗牛慢慢爬 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 ...

随机推荐

  1. windows程序移植linux

    1,路径名统一用正斜杠“/”.(windows下正反斜杠都识别,linux只认正斜杠.) 2,统一使用UTF-8格式编码. vim中无法保存汉字时,可输入下列命令: :set fileencoding ...

  2. 转】Linux下安装Tomcat服务器和部署Web应用

    原博文出自于: http://www.cnblogs.com/xdp-gacl/p/4097608.html 感谢! 一.上传Tomcat服务器

  3. 转】MyEclipse使用总结——设置MyEclipse开发项目时使用的JDK

    原博文出自于: http://www.cnblogs.com/xdp-gacl/p/3927677.html 感谢! 安装好MyEclipse之后,在MyEclipse中开发项目时,默认使用的是MyE ...

  4. 移动Web单页应用开发实践——页面结构化

    1. 前言 在开发面向现代智能手机的移动Web应用的时候,无法避免一个事实,就是需要开发单页应用(Single Page WebApp).对于不同的系统需求,单页应用的粒度会不同,可能是整个系统都使用 ...

  5. HDU 1525 Euclid's Game (博弈)

    Euclid's Game Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Tot ...

  6. hdu 5532 Almost Sorted Array

    http://acm.hdu.edu.cn/showproblem.php?pid=5532  题目大意: 给你一个不规则的序列,问是否能够通过删除一个元素使其成为一个有序的序列(递增或递减(其中相邻 ...

  7. UVALive 7077 - Song Jiang's rank list(模拟)

    https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_probl ...

  8. Maven Archetype Plugin

    使用Archetype的一般步骤 命令——mvn archetype:generate 输入命令后,Archetype插件会输出一个Archetype列表供用户选择:选择自己想要使用的Archetyp ...

  9. 接口是干爹, 继承是亲爹 ---JAVA

    接口(interface)是干爹, 因为你可以有很多很多的干爹爹... 继承(extends)是亲爹, 因为你只能有一个父类, 只有一个亲生的父亲. 单继承,多接口?./>./..

  10. Light oj 1100 - Again Array Queries (鸽巢原理+暴力)

    题目链接:http://www.lightoj.com/volume_showproblem.php?problem=1100 给你n个数,数的范围是1~1000,给你q个询问,每个询问问你l到r之间 ...