【LeetCode】23. Merge k Sorted Lists 解題報告(Python)
阿新 • • 發佈:2018-12-15
題目描述:
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
時間卡在了每次查詢連結串列最小元素這一步,導致超時。
時間複雜度是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 日 —— 下雨天還是挺舒服的