1. 原始题目
合并 k 个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。
示例:
输入: [ 1->4->5, 1->3->4, 2->6 ] 输出: 1->1->2->3->4->4->5->6
2. 解题
思路1. 优先队列。即自动排序的队列。
将所有链表结点依次进队,此时结点已排好序,再分别出队组成新链表即可。
注:python3的优先队列:
from queue import PriorityQueue
有了优先队列,这个题就是easy了:
1 class Solution: 2 def mergeKLists(self, lists: List[ListNode]) -> ListNode: 3 q = PriorityQueue() 4 dummy = ListNode(None) 5 head = dummy 6 for node in lists: 7 while(node): 8 q.put(node.val) 9 node = node.next 10 while not q.empty(): 11 dummy.next = ListNode(q.get()) 12 dummy = dummy.next 13 14 dummy.next = None 15 16 return head.next
思路2.DP动态规划
首先递归实现两个链表的合并:
1 def MergeTwoList(self,phead1,phead2): 2 if not phead1: return phead2 3 if not phead2: return phead1 4 node = ListNode(0) 5 6 if phead1.val>phead2.val: 7 node = phead2 # 指向一个新结点 8 node.next = self.MergeTwoList(phead1,phead2.next) # 合并一个两个新的链表 9 else: 10 node = phead1 11 node.next = self.MergeTwoList(phead1.next,phead2) 12 return node
接着动态规划实现多个链表的合并:思路是列表中k个链表的合并,可以看作两个子列表的合并,即 0~k/2 这个列表中的链表 和 k/2~k个列表中的链表的合并。
然后继续将两个子列表折半,再折半...停止递归的条件有三个:空列表返回None;列表中只有1个元素,返回该单个链表;列表中只有2个元素,调用两个链表合并的函数实现合并!
整体代码如下:
1 class Solution: 2 def MergeTwoList(self,phead1,phead2): # 合并两个链表 3 if not phead1: return phead2 4 if not phead2: return phead1 5 node = ListNode(0) 6 7 if phead1.val>phead2.val: 8 node = phead2 9 node.next = self.MergeTwoList(phead1,phead2.next) 10 else: 11 node = phead1 12 node.next = self.MergeTwoList(phead1.next,phead2) 13 return node 14 15 def mergeKLists(self, lists) -> ListNode: # 合并多个链表 16 17 if len(lists)==0: return None # 递归停止的第一个条件 18 if len(lists)==1: return lists[0] # 递归停止的第二个条件 19 if len(lists)==2: return self.MergeTwoList(lists[0], lists[1]) # 递归停止的第三个条件 20 mid = int(len(lists)/2) # 列表中的所有链表分成两部分 21 node1 = [] 22 for i in range(mid): # 左边一半 23 node1.append(lists[i]) 24 node2 = [] 25 for i in range(mid,len(lists)): # 右边一半 26 node2.append(lists[i]) 27 28 return self.MergeTwoList(self.mergeKLists(node1), self.mergeKLists(node2)) # 这句话最关键!两个子列表合并完之后,实现两个链表的合并!
验证:
1 # 新建链表1 2 listnode1 = ListNode_handle(None) 3 s1 = [2,7,26,47,86,90] 4 for i in s1: 5 listnode1.add(i) 7 listnode1.print_node(listnode1.head) 8 9 # 新建链表2 10 listnode2 = ListNode_handle(None) 11 s2 = [1,5,6,78,92] 12 for i in s2: 13 listnode2.add(i) 14 listnode2.print_node(listnode2.head) 15 16 # 新建链表3 17 listnode3 = ListNode_handle(None) 18 s3 = [12,15,16,178,192] 19 for i in s3: 20 listnode3.add(i) 21 listnode3.print_node(listnode3.head)
s=Solution()
listnode1.print_node(s.mergeKLists([listnode1.head, listnode2.head, listnode3.head]))
2 7 26 47 86 90
1 5 6 78 92
12 15 16 178 192
1 2 5 6 7 12 15 16 26 47 78 86 90 92 178 192