合并K个升序链表
· 约 3 分钟阅读 · – 次阅读
leetcode
23. 合并K个升序链表
给你一个链表数组,每个链表都已经按升序排列。
请你将所有链表合并到一个升序链表中,返回合并后的链表。
示例 1:
输入:lists = [[1,4,5],[1,3,4],[2,6]] 输出:[1,1,2,3,4,4,5,6] 解释:链表数组如下: [ 1->4->5, 1->3->4, 2->6 ] 将它们合并到一个有序链表中得到。 1->1->2->3->4->4->5->6 示例 2:
输入:lists = [] 输出:[] 示例 3:
输入:lists = [[]] 输出:[]
没想到居然是一个困难题
循环使用 2个链表合并的思路处理
时间复杂度:由于除第一个链表外,其他每个链表都要被遍历多次, 等差数列: 第一次合并后,链表长度:2n 第二次合并后,链表长度:3n 第k-1次合并后,链表长度:kn 合计遍历(2+k)n*(k-1)/2=O(k^2*n)
空间复杂度O(1)
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def mergeKLists(self, lists: List[Optional[ListNode]]) -> Optional[ListNode]:
def mergeTwoLists(list1, list2):
dummy = ListNode()
p = dummy
while list1 and list2:
if list1.val < list2.val:
p.next = list1
list1 = list1.next
else:
p.next = list2
list2 = list2.next
p = p.next
p.next = list1 if list1 else list2
return dummy.next
if len(lists) == 0:
return None
p = lists[0]
for i in range(1, len(lists)):
p = mergeTwoLists(p, lists[i])
return p
分治+归并
k个数组,先两两合并,然后逐步归并。 划分深度为logk层,每层每个数都要遍历一次,每层k*n个数 时间复杂度O(logk * kn) 空间复杂度:栈空间logk, 若改为递归,则实际需要kn的额外空间
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def mergeKLists(self, lists: List[Optional[ListNode]]) -> Optional[ListNode]:
def mergeTwoLists(list1, list2):
if not list1: return list2
if not list2: return list1
dummy = ListNode()
p = dummy
while list1 and list2:
if list1.val < list2.val:
p.next = list1
list1 = list1.next
else:
p.next = list2
list2 = list2.next
p = p.next
p.next = list1 if list1 else list2
return dummy.next
def mergeHelper(lists, left, right):
if left == right: return lists[left]
if left < right:
mid = left + (right-left)//2
list1 = mergeHelper(lists, left, mid)
list2 = mergeHelper(lists, mid+1, right)
return mergeTwoLists(list1, list2)
else:
return None
return mergeHelper(lists, 0, len(lists)-1)
同时比较k个链表中开头的值,并用最小堆优化
时间复杂度:n个节点,k为最小堆的大小,每个节点必进出最小堆一次,堆调整O(logk),整体O(nlogk) 空间复杂度:即为堆的大小,O(logk)
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def mergeKLists(self, lists: List[Optional[ListNode]]) -> Optional[ListNode]:
from heapq import heappush, heappop
heaq = []
for i in range(len(lists)):
if lists[i]:
heappush(heaq, (lists[i].val, i))
dummy = ListNode()
head = dummy
while heaq:
_, min_index = heappop(heaq)
head.next = lists[min_index]
head = head.next
lists[min_index] = lists[min_index].next
if lists[min_index]:
heappush(heaq, (lists[min_index].val, min_index))
return dummy.next