思路
流程
1、根据每个链表中第一个元素对链表进行顺序排序
2、对排好序的列表,取其第一个链表中的第一个元素,放入ret链表
3、将第一个链表中的第一个元素移除,若移除后该链表为空则从列表中移除该链表
4、此时列表中链表的顺序因为第一个链表中的第一个元素已经改变而被打乱,所以需要将
第一个链表插到合适的位置,使得列表保持顺序,然后循环进行上述操作直至列表长度为零
可优化
1、创建0~n顺序到链表下标的一个映射,可以直接操作key到index的映射达到排序的目的,从而避免因排序需要频繁的移动链表造成大量的时间开销
2、每次调整列表顺序时,代码采用的时全部重排,事实上列表整体有序,仅有列表中第一个元素需要调整
代码
class Solution:
def mergeKLists(self, lists: List[Optional[ListNode]]) -> Optional[ListNode]:
# 头节点
ret = ListNode()
# 指向ret尾部的节点,方便添加节点
last = ret
# 保留非null节点
valid_lists = []
for node in lists:
if(node!=None):
valid_lists.append(node)
# 根据每个节点的第一个元素排序
valid_lists.sort(key=lambda x:x.val)
while(len(valid_lists)!=0):
# 节点添加
last.next = ListNode(val=valid_lists[0].val,next=None)
# 指向尾部节点
last = last.next
# 当前节点的下一个节点非空,转至下一个节点
if(valid_lists[0].next!=None):
valid_lists[0] = valid_lists[0].next
# 当前节点下一个节点为空,说明以当前节点为head的链表已经遍历,可移除
else:
valid_lists.pop(0)
# 对调整后的节点根据第一个元素重新排序
# 其实只需要对第一个节点进行插入,因为其他节点都是顺序,以降低时间复杂度
valid_lists.sort(key=lambda x:x.val)
return ret.next