[LeetCode] 23.合并K个排序链表

题目

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

示例:

输入:
[
1->4->5,
1->3->4,
2->6
]
输出: 1->1->2->3->4->4->5->6
用时最短

class Solution:
    def mergeKLists(self, lists: List[ListNode]) -> ListNode:
        
        dummy = pre = ListNode(-1)
        nums = []
        for node in lists:
            while node:
                nums.append(node)
                node = node.next
        for node in sorted(nums,key=lambda n:n.val):
            pre.next = node
            pre = pre.next
        
        return dummy.next

最小堆

from heapq import heapify, heappop
class Solution:
    def mergeKLists(self, lists: List[ListNode]) -> ListNode:
        # 读取所有的节点值
        h = []
        for node in lists:
            while node:
                h.append(node.val)
                node = node.next
        # 构造一个最小堆
        if not h:
            return None
        heapify(h)  # 转换成最小堆
        # 构造链表
        root = ListNode(heappop(h))
        curnode = root
        while h:
            nextnode = ListNode(heappop(h))
            curnode.next = nextnode
            curnode = nextnode
        return root
        

分治解法

class Solution:
    def mergeTwoLists(l1: ListNode, l2: ListNode) -> ListNode:
        l = ListNode(0)
        temp = l
        while l1 or l2:
            if not l1:
                temp.next = l2
                break
            elif not l2:
                temp.next = l1
                break 
            v1 = l1.val
            v2 = l2.val
            if l1.val < v2 :
                temp.next = ListNode(v1)
                l1 = l1.next
            else:
                temp.next = ListNode(v2)
                l2 = l2.next
            temp = temp.next
        return l.next
    def mergeKLists(self, lists: List[ListNode]) -> ListNode: 
        lens = len(lists)
        if not lens:
            return None
        elif lens == 1:
            return lists[0]
        elif lens ==2:
            return Solution.mergeTwoLists(lists[0],lists[1])
        mid = lens//2
        l1 = []
        l2 = []
        for i in range(mid):
            l1.append(lists[i])
        for i in range(mid,lens):
            l2.append(lists[i])
        return Solution.mergeTwoLists(self.mergeKLists(l1),self.mergeKLists(l2))

普通解法

class Solution:
    def mergeKLists(self, listss: List[ListNode]) -> ListNode:   
        l = ListNode(0)
        temp = l
        lists = []
        for node in listss:
            if  node :
                lists.append(node)
        while lists:
            minval = lists[0].val
            index = 0
            # minval = 8
            for i in range(len(lists)):
                if lists[i].val < minval:
                    minval, index = lists[i].val, i
                    print('min:',minval, 'index:',index)
            temp.next = ListNode(minval)
            lists[index] = lists[index].next
            if not lists[index]:
                lists.remove(lists[index])
                print('remove:',index)
            temp = temp.next
        return l.next

lambda相关

lambda作为一个表达式,定义了一个隐函数,上例的代码n为入口参数,n.val为函数体

最小堆相关

最小堆是一棵完全二叉树,非叶子结点的值不大于左孩子和右孩子的值。

分治相关

分治法得基本步骤:
  step1 分解:将原问题分解为若干个规模较小,相互独立,与原问题形式相同的子问题;

step2 解决:若子问题规模较小而容易被解决则直接解,否则递归地解各个子问题

step3 合并:将各个子问题的解合并为原问题的解。

它的一般的算法设计模式如下:
  Divide-and-Conquer(P )
  1. if |P|≤n0
  2. then return(ADHOC(P ))
  3. 将P分解为较小的子问题 P1 ,P2 ,…,Pk
  4. for i←1 to k
  5. do yi ← Divide-and-Conquer(Pi) △ 递归解决Pi
  6. T ← MERGE(y1,y2,…,yk) △ 合并子问题
  7. return(T)

其中|P|表示问题P的规模;n0为一阈值,表示当问题P的规模不超过n0时,问题已容易直接解出,不必再继续分解。ADHOC (p )是该分治法中的基本子算法,用于直接解小规模的问题P。因此,当P的规模不超过n0时直接用算法ADHOC(p )求解。算法MERGE(y1,y2,…,yk)是该分治法中的合并子算法,用于将P的子问题P1 ,P2 ,…,Pk的相应的解y1,y2,…,yk合并为P的解。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值