【LeetCode】23. Merge k Sorted Lists 合并K个升序链表
- 作者: 负雪明烛
- id: fuxuemingzhu
- 个人博客:http://fuxuemingzhu.cn/
- 个人公众号:负雪明烛
- 本文关键词:合并,链表,单链表,题解,leetcode, 力扣,Python, C++, Java
题目地址: https://leetcode.com/problems/merge-k-sorted-lists/description/
题目描述:
Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.
Example:
Input:
[
1->4->5,
1->3->4,
2->6
]
Output: 1->1->2->3->4->4->5->6
题目大意
把一个链表里的k个有序链表合并成一个有序链表。
解题方法
方法一:每次遍历最小值(TLE)
这个题是21. Merge Two Sorted Lists的拓展,属于经典题目,很容易想到的方法就是每次在lists中查找最小的值,然后拼接到现在的链表尾部。需要注意的是,我们不能通过修改链表指针的方法来更新lists里的头部元素,所以只能强行赋值更新lists。
时间卡在了每次查找链表最小元素这一步,导致超时。
时间复杂度是O(N*K),空间复杂度是O(1)。N是结果链表的长度,K是每次题目给出的链表个数。
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def mergeKLists(self, lists):
"""
:type lists: List[ListNode]
:rtype: ListNode
"""
head = ListNode(-1)
move = head
while True:
curHead = ListNode(float('inf'))
curIndex = -1
for i, llist in enumerate(lists):
if llist and llist.val < curHead.val:
curHead = llist
curIndex = i
if curHead.val == float('inf'):
break
curNext = curHead.next
move.next = curHead
curHead.next = None
move = curHead
curHead = curNext
lists[curIndex] = curHead
return head.next
方法二:小根堆保存值和索引
这个方法是根据上面超时的情况自然想出来的,我们每次需要用的是K个链表头结点的最小值,所以把每个链表的头结点都放在一个小根堆里面。这样,每次弹出来的就是最小链表的值,然后根据这个值的索引去Lists中找到对应节点,拼接到末尾就行。
有人使用的弹出堆里面最小的值,然后重新生成新的节点的方式,这样不好。
另外,代码里需要注意的一个问题是,和方法一一样,需要更新链表的头结点才行,不能直接通过修改指针的方式修改,必须直接赋值更新。如果这个步骤少了的话,按照索引查找就一直获取的是老节点。
时间复杂度是O(N),空间复杂度是O(1)。N是结果链表的长度,K是每次题目给出的链表个数。
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def mergeKLists(self, lists):
"""
:type lists: List[ListNode]
:rtype: ListNode
"""
head = ListNode(-1)
move = head
heap = []
heapq.heapify(heap)
[heapq.heappush(heap, (l.val, i)) for i, l in enumerate(lists) if l]
while heap:
curVal, curIndex = heapq.heappop(heap)
curHead = lists[curIndex]
curNext = curHead.next
move.next = curHead
curHead.next = None
move = curHead
curHead = curNext
if curHead:
lists[curIndex] = curHead
heapq.heappush(heap, (curHead.val, curIndex))
return head.next
方法三:小根堆保存值和节点
对于Python3,不能直接在堆里面保存节点,因为会造成无法比较的问题。但是对于python2就可以这么做了,所以可以直接把节点的值和节点直接保存到堆里面,这样每次弹出来的是最小的值的节点,直接使用就好了。
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def mergeKLists(self, lists):
"""
:type lists: List[ListNode]
:rtype: ListNode
"""
head = ListNode(-1)
move = head
heap = []
heapq.heapify(heap)
[heapq.heappush(heap, (l.val, l)) for i, l in enumerate(lists) if l]
while heap:
curVal, curHead = heapq.heappop(heap)
curNext = curHead.next
move.next = curHead
curHead.next = None
move = curHead
curHead = curNext
if curHead:
heapq.heappush(heap, (curHead.val, curHead))
return head.next
时间复杂度是O(N),空间复杂度是O(1)。N是结果链表的长度,K是每次题目给出的链表个数。
参考资料:
日期
2018 年 10 月 16 日 —— 下雨天还是挺舒服的
【LeetCode】23. Merge k Sorted Lists 合并K个升序链表的更多相关文章
- [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 ...
- LeetCode 21. Merge Two Sorted Lists合并两个有序链表 (C++)
题目: Merge two sorted linked lists and return it as a new list. The new list should be made by splici ...
- leetcode 21 Merge Two Sorted Lists 合并两个有序链表
描述: 合并两个有序链表. 解决: ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) { if (!l1) return l2; if (!l2) ...
- 【LeetCode】Merge Two Sorted Lists(合并两个有序链表)
这道题是LeetCode里的第21道题. 题目描述: 将两个有序链表合并为一个新的有序链表并返回.新链表是通过拼接给定的两个链表的所有节点组成的. 示例: 输入:1->2->4, 1-&g ...
- [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 ...
- [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 ...
- [LeetCode] Merge k Sorted Lists 合并k个有序链表
Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. 这 ...
- [Leetcode] Merge k sorted lists 合并k个已排序的链表
Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. 思 ...
- Leetcode 23.Merge Two Sorted Lists Merge K Sorted Lists
Merge Two Sorted Lists Merge two sorted linked lists and return it as a new list. The new list shoul ...
随机推荐
- python爬虫之正则表达式(用在其他地方也可)
1. 常用的匹配规则 ### 常用的匹配规则 # \w 匹配字母.数字及下划线 # \W 匹配不是字母.数字及下划线的字符 # \s 匹配任意空白字符,等价于[\t\n\t\f] # \S 匹配任意非 ...
- Django向数据库批量插入数据
# 如何向数据库一次性插入多条数据 # 方法一:效率极低,不推荐使用 for i in range(1000): models.Book.objects.create(title=f'第{i}本书') ...
- mongodb数据库简单类
<?php/*** Mongodb类** examples: * $mongo = new HMongodb("127.0.0.1:11223"); * $mongo-> ...
- C语言之内核中的struct list_head 结构体
以下地址文章解释很好 http://blog.chinaunix.net/uid-27122224-id-3277511.html 对下面的结构体分析 1 struct person 2 { 3 in ...
- 学习java 7.15
学习内容: 进程:正在运行的程序 是系统进行资源分配和调用的独立单位 每个进程都有它自己的内存空间和系统资源 线程:是进程中的单个顺序控制流,是一条执行路径 单线程:一个进程如果只有一条执行路径,则称 ...
- 用usb线配置直流电机驱动器不能配置成功
原因可能是因为usb线的问题 换了三条usb线. 这三条都是通的,用万用表测试都是通的,但是进行电机配置的时候不行. 猜测原因可能是三条usb线的芯材质不同导致压降不同,使得通信故障.
- Oracle—网络配置文件
Oracle网络配置文件详解 三个配置文件 listener.ora.sqlnet.ora.tnsnames.ora ,都是放在$ORACLE_HOME/network/admin目录下. 1 ...
- windows下的_vimrc
折腾了一天 在https://keelii.github.io/2016/06/13/awsome-window-vimrc/的基础上进行了一些改动 " ------------------ ...
- 4.2 rust 命令行参数
从命令行读取参数 use std::env; fn main() { let args: Vec<String> = env::args().collect(); println!(&q ...
- Android 高级UI组件(一)GridView与ListView
1.GridView 1.GridView学习 GridView和ListView都是比较常用的多控件布局,而GridView更是实现九宫图的首选 main.xml: <?xml version ...