个人题解,暴力:
1.每次查找所有链表的最小值
2.有节点则更新角标和最小值
3.一次循环完,角标和最小值均被更新过,则说明还有这一轮还有节点;没则退出循环
4.当循环中没有发生更新说明都添加完了
# 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]:
if len(lists) == 0:
return None
ans, min_now, min_index = ListNode(), inf, inf
now_node = ans
flag = 0
for node in lists:
if node != None:
flag = 1
break
if flag == 0:
return None
while True:
for i, node in enumerate(lists):
if node != None:
if node.val < min_now:
min_index = i
min_now = node.val
if min_index != inf and min_now != inf:
now_node.next = lists[min_index]
now_node = now_node.next
lists[min_index] = lists[min_index].next
min_index, min_now = inf, inf
else:
break
return ans.next
大佬题解:
思路一、
建堆,因为堆适用于每次取出最大或最小,且插入元素的时间复杂度是O(logk),k为堆中元素个数
而每次需要插入的节点为每个链链首中最小的,下一个的道理等同
ListNode.__lt__ = lambda a, b: a.val < b.val # 让堆可以比较节点大小
class Solution:
def mergeKLists(self, lists: List[Optional[ListNode]]) -> Optional[ListNode]:
cur = dummy = ListNode() # 哨兵节点,作为合并后链表头节点的前一个节点
h = [head for head in lists if head] # 初始把所有链表的头节点入堆
heapify(h) # 堆化
while h: # 循环直到堆为空
node = heappop(h) # 剩余节点中的最小节点
if node.next: # 下一个节点不为空
heappush(h, node.next) # 下一个节点有可能是最小节点,入堆
cur.next = node # 合并到新链表中
cur = cur.next # 准备合并下一个节点
return dummy.next # 哨兵节点的下一个节点就是新链表的头节点
二、递归合并
class Solution:
# 21. 合并两个有序链表
def mergeTwoLists(self, list1: Optional[ListNode], list2: Optional[ListNode]) -> Optional[ListNode]:
cur = dummy = ListNode() # 用哨兵节点简化代码逻辑
while list1 and list2:
if list1.val < list2.val:
cur.next = list1 # 把 list1 加到新链表中
list1 = list1.next
else: # 注:相等的情况加哪个节点都是可以的
cur.next = list2 # 把 list2 加到新链表中
list2 = list2.next
cur = cur.next
cur.next = list1 if list1 else list2 # 拼接剩余链表
return dummy.next
def mergeKLists(self, lists: List[Optional[ListNode]]) -> Optional[ListNode]:
m = len(lists)
if m == 0: return None # 注意输入的 lists 可能是空的
if m == 1: return lists[0] # 无需合并,直接返回
left = self.mergeKLists(lists[:m // 2]) # 合并左半部分
right = self.mergeKLists(lists[m // 2:]) # 合并右半部分
return self.mergeTwoLists(left, right) # 最后把左半和右半合并
参考来源:作者:灵茶山艾府
链接:https://leetcode.cn/problems/merge-k-sorted-lists/solutions/2384305/liang-chong-fang-fa-zui-xiao-dui-fen-zhi-zbzx/