题意:

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. javascript面向对象事件继承

    继承:父类有的,子类也有.父类改变,子类也跟着变. 属性继承:      矫正this (window对象,矫正成object对象)     fn .call(this是谁,参数1,参数2...); ...

  2. c++builder 重载WindowProc、WndProc 截获消息

    c++builder 重载WindowProc.WndProc 截获消息 方法一WindowProc void __fastcall  myWindowProc(Messages::TMessage ...

  3. Dagger学习笔记

    @Inject 提供依赖的构造函数,或者需要依赖的成员变量 @Module 提供依赖,实例化的地方( 使用module实例化,方便测试的时候替换成其他对象,而这也是和构造方法注入的区别,如果用构造方法 ...

  4. shell's glob

    [shell's glob] basic glob example: range glob example: 参考: http://bash.cumulonim.biz/glob.html

  5. ACM之数学题

    数学题,始终记得,第一次被带飞师大校赛以及省赛,毫无例外的在数学题上卡死....因此,现在开始,有意识的保留遇见的数学题...(下列知识点按遇见先后顺序排列: 1欧拉公式 欧拉公式的用处是,找出小于N ...

  6. 第二次作业----自学c++的选择与计划

    1.选择慕课网进行学习的原因 由于本来寒假是打算学习java的(如上篇随笔所言),所以向之前已经自学的同学问如何找教学视频,他就向我推荐了慕课网,在看了几集java的教学视频之后觉得慕课网挺好用的,所 ...

  7. jgroups 入门

    官网地址:http://www.jgroups.org/ 聊天室示例:http://www.jgroups.org/tutorial/html/ch02.html 2.1. JGroups overv ...

  8. IIS 7 WAS服务不可用

    在 Windows Server 2008 上使用 %windir%\system32\inetsrv\appcmd.exe list wp 命令,得到如下错误: ERROR ( message:WA ...

  9. ecshop读写分离

    1.配置文件设置 $db_name = "ecshop"; $prefix = "ecs_"; $timezone = "Europe/Berlin& ...

  10. 使用struts2实现文件下载

    <action name="downloadAction" class=""> <result type="stream" ...