【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 ...
随机推荐
- window文件挂载到linux
- 38- Majority Element
Majority Element My Submissions QuestionEditorial Solution Total Accepted: 110538 Total Submissions: ...
- SpringBoot Profiles 多环境配置及切换
目录 前言 默认环境配置 多环境配置 多环境切换 小结 前言 大部分情况下,我们开发的产品应用都会根据不同的目的,支持运行在不同的环境(Profile)下,比如: 开发环境(dev) 测试环境(tes ...
- springcloud - alibaba - 3 - 整合config - 更新完毕
0.补充 1.需求 如果我有这么一个请求:我想要gitee中的配置改了之后,我程序yml中的配置也可以跟着相应产生变化,利用原生的方式怎么做?一般做法如下: 而有了SpringCloud-alibab ...
- flink03-----1.Task的划分 2.共享资源槽 3.flink的容错
1. Task的划分 在flink中,划分task的依据是发生shuffle(也叫redistrubute),或者是并行度发生变化 1. wordcount为例 package cn._51doit ...
- 关于stm32不常用的中断,如何添加, 比如timer10 timer11等
首先可以从keil中找到 比如找到定时器11的溢出中断,如上图是26 然后,配置定时器11 溢出中断的时候,我就在:下面填上这个变量. 之后要写中断服务函数,也就是发生中断后要跳转到的函数. 需要知道 ...
- 集合类——Collection、List、Set接口
集合类 Java类集 我们知道数组最大的缺陷就是:长度固定.从jdk1.2开始为了解决数组长度固定的问题,就提供了动态对象数组实现框架--Java类集框架.Java集合类框架其实就是Java针对于数据 ...
- Java操作csv文件
以前就一直很想搞懂一个问题就是java如何读取和写入csv文件,现在要花时间总结一波. 主要使用的javaCSV.jar javaCSV API:http://javacsv.sourceforge. ...
- C++ default constructor | Built-in types
Predict the output of following program? 1 #include <iostream> 2 using namespace std; 3 4 int ...
- 【Java 8】Predicate详解
一.java.util.function.Predicate 这里类是java自带主要广泛用在支持lambda表达式的API中. 1.接口源码 @FunctionalInterface public ...