leetcode day 6 【23. 合并K个升序链表】在图书馆苦思冥想的一天

在这里插入图片描述

解题:

- 第一种方法:

从第二个链表开始,将每一个链表插入到前面基本链表中,这个更新后的链表作为基本链表。

暴力解法:对新插入的链表中的每一个元素都去基本链表中从头找自己要插入的位置

暴力解法稍稍优化后:对新插入的链表中的每一个元素都去基本链表中找自己要插入的位置,起始头从当前插入位置开始。

# 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[ListNode]) -> ListNode:
        if lists:
            head = ListNode()
            head.next = lists[0]
            for node in lists[1:]:
                frontnode = head
                basenode = frontnode.next
                while (node):
                    while(basenode and node.val >= basenode.val):
                        frontnode = basenode
                        basenode = basenode.next
                    frontnode.next = node
                    if basenode == None:
                        break
                    while(node.next and node.next.val < basenode.val):
                        node = node.next
                    tmpnode = node.next
                    node.next = basenode
                    frontnode = node
                    node = tmpnode
            return head.next
        else:
            return None

在这里插入图片描述

  • 继续优化:

1.找第一个插入的位置可以不用顺序查找而用二分查找。
2.每次遍历完有一定的先验知识了,可以用哈希表之类的存储,对下一个链表的插入提供帮助。【空间换时间】

- 第二种方法:

基本思路:k个列表k个指针,从k个列表中pick出最小值的结点,然后该列表的头指针后移一位。循环,直到所有节点被pick。
在这里插入图片描述
优化:如果每次都临时比较,那么每个被pick的节点要进行k次比较,共kn个节点,复杂度就是k^2 ✖n。但实际上每轮比较只会pick出1个,剩下k-1个应该可以有序排列了,这样可以有助于下次pick。因此,选用优化队列(堆)这种数据结构来实现该功能,可将比较复杂度从k降低至logk。

import heapq
# 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[ListNode]) -> ListNode:
        def __lt__(self, other):
            return self.val < other.val
        ListNode.__lt__ = __lt__
        head = tail = ListNode()
        q = []
        for l in lists:
            if l:
                heapq.heappush(q,l)
        while q:
            node = heapq.heappop(q)
            tail.next = node
            tail = tail.next
            if node.next:
                heapq.heappush(q, node.next)
        return head.next



在这里插入图片描述

- 第三种方法:

基本思路
归并排序(分而治之)对于第一种方法的逐一合并,可以采用分而治之。链表两两配对合并。复杂度为nklogk
在这里插入图片描述

# 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[ListNode]) -> ListNode:
        if lists:
            return self.mergeTwoLists(lists[0:int(len(lists)/2)], lists[int(len(lists)/2):])
        else:
            return None
            
    def mergeTwoLists(self, A: List[ListNode], B: List[ListNode]) -> ListNode:
        if len(A) > 1:
            A = self.mergeTwoLists(A[0:int(len(A)/2)], A[int(len(A))/2:])
        elif A == []:
            A = None
        else:
            A = A[0]
        if len(B) > 1:
            B = self.mergeTwoLists(B[0:int(len(B)/2)], B[int(len(B)/2):])
        elif B == []:
            B = None
        else:
            B = B[0]
        head = ListNode()
        frontnode = head
        head.next, basenode = A, A
        node = B
        while node:
            while(basenode and node.val >= basenode.val):
                frontnode = basenode
                basenode = basenode.next
            frontnode.next = node
            if basenode == None:
                break
            while(node.next and node.next.val < basenode.val):
                node = node.next
            tmpnode = node.next
            node.next = basenode
            frontnode = node
            node = tmpnode
        return head.next
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值