前言:
“合并K个升序链表”的题目是力扣题库上的第23题。我是使用Python3编写的解法,性能算不上好,在此仅仅只是阐述一下解法编程思想。仅供参考~
解法上可能会跟别人相同,所以要是看不懂下面的阐述的话可以去力扣对应的题目上查看其他人的解题思路~
问题描述:
题目的要求是:给你一个链表数组,每个链表都已经按升序排列。
请你将所有链表合并到一个升序链表中,返回合并后的链表。
LeetCode官方给的示例如下:
示例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 = [[]]
输出:[]
提示:
- k == lists.length
- 0 <= k <= 10^4
- 0 <= lists[i].length <= 500
- -10^4 <= lists[i][j] <= 10^4
- lists[i] 按 升序 排列
- lists[i].length 的总和不超过 10^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]:
# 合并链表
def getSortNode(nodeList,ans,numList):
# 查找numList中的最小值
num=min(numList)
# 获取numList最小值的下标
index=numList.index(num)
# 取出nodeList中值最小的节点
ans=nodeList[index]
# 值最小的节点所在的链表的下一个节点变成首个节点
nodeList[index]=nodeList[index].next
# 判断选中的链表是否为空链表了
if nodeList[index] is None:
# 删除空链表及对应的numList
numList.pop(index)
nodeList.pop(index)
else:
# 将选中的链表新的节点值赋给numList对应的位置
numList[index]=nodeList[index].val
# 判断当前链表数组是否没有链表了
if numList!=[]:
# 当前链表数组还有链表,递归调用合并函数,并将ans的下一个结点等于递归调用后的返回值
ans.next=getSortNode(nodeList,ans,numList)
# 返回ans
return ans
# 用于存放每个链表的首个节点的值
numList=[]
# 用于存放删除空链表后的链表数组
nodeList=[]
# 获取非空的链表及对应的首个节点的值
for i in range(len(lists)):
if lists[i] is not None:
numList.append(lists[i].val)
nodeList.append(lists[i])
# 判断传入的链表数组中的链表是有存在数据的链表
if numList!=[]:
# 合并链表,ans为合并完成的链表,即结果
ans=getSortNode(nodeList,None,numList)
else:
# 传入的链表数组中不存在有数据的链表,ans为None
ans=None
return ans
运行结果: