题意:

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. php框架推荐

    ThinkPHP,  国内开发的框架,特别容易入门,中文文档细致,表述准确. Laravel, 国外框架,非常高级的一个框架,特别是前端比较模块化,但入门难一些,速度不高. laravel在lampp ...

  2. C#.Net 导出Excel 之单元格 相关设置

    range.NumberFormatLocal = "@";     //设置单元格格式为文本range = (Range)worksheet.get_Range("A1 ...

  3. oracle max()函数和min()函数

    当需要了解一列中的最大值时,可以使用MAX()函数:同样,当需要了解一列中的最小值时,可以使用MIN()函数.语法如下. SELECT          MAX (column_name) / MIN ...

  4. USB的四种传输类型

    USB协议规定了4种传输类型:批量(bulk)传输,等时传输(同步传输),中断传输和控制传输.

  5. linux常用基本命令

    Linux中许多常用命令是必须掌握的,这里将我学linux入门时学的一些常用的基本命令分享给大家一下,希望可以帮助你们.   系统信息 arch 显示机器的处理器架构(1) uname -m 显示机器 ...

  6. Android打开WIFI或者移动网络的代码实现

    MainActivity如下: package wy.testnetwork; import java.lang.reflect.Field; import java.lang.reflect.Inv ...

  7. CSU1612Destroy Tunnels(强连通)

    Destroy Tunnels 原来早忘记了离散里含有这么一个叫传递闭包的东西 矩阵A的闭包B = A U A^2 U A^3 U ... 所以这里直接如果A[i][j]!= 0,建边i->j跑 ...

  8. UVaLive 6809 Spokes Wheel (模拟)

    题意:给定两个16进制数,问你把它转成二进制后,把第一个向左或者向右旋转最少的次数同,使得第一个变成第二个. 析:也是比较水的,按照要求做就好,注意0的情况,可能会忘记. #pragma commen ...

  9. [置顶] Linux信号相关笔记

    最近又温习了一遍Linux中的信号知识,发现有很多东西以前没有注意到,就通过这篇博客记录一下,巩固一下知识点. 一,信号基础: 信号是什么?为了回答这个问题,首先要从异常说起,这里的异常不是指c++/ ...

  10. JDK - Tomcat - Eclipse - JSP - Servlet 配置运行全攻略

    花了将近两个月的时间,从 JDK 开始一步一步摸索,历经千辛万苦,终于让第一个 Servlet 运行起来了,创建第一个 Servlet  程序确实要比创建第一个 Asp.net 程序困难多了,但是不要 ...