zoukankan      html  css  js  c++  java
  • **23. Merge k Sorted Lists

    1. 原始题目

    合并 个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。

    示例:

    输入:
    [
      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

  • 相关阅读:
    09-23
    21-9-18日记1
    paho mqtt库使用记录
    UIS8811 的 NB-IOT 初认识(21-9-10工作记录 )
    go语言之异常捕获
    【原创】数据库基础之PostgreSQL
    【原创】Linux基础之fail2ban
    【原创】大叔经验分享(132)mac os 12启动idea失败
    【原创】大数据基础之Hadoop(3)hdfs diskbalancer
    【转】常用 Git 命令清单
  • 原文地址:https://www.cnblogs.com/king-lps/p/10685155.html
Copyright © 2011-2022 走看看