力扣hot100之# Definition for singly-linked list.# class ListNode:# def __init__(self, val=0, next

个人题解,暴力:

1.每次查找所有链表的最小值

2.有节点则更新角标和最小值

3.一次循环完,角标和最小值均被更新过,则说明还有这一轮还有节点;没则退出循环

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]:
        if len(lists) == 0:
            return None
        ans, min_now, min_index = ListNode(), inf, inf
        now_node = ans
        flag = 0
        for node in lists:
            if node != None:
                flag = 1
                break
        if flag == 0:
            return None 
        while True:            
            for i, node in enumerate(lists):
                if node != None:
                    if node.val < min_now:
                        min_index = i
                        min_now = node.val
            if min_index != inf and min_now != inf:
                now_node.next = lists[min_index]
                now_node = now_node.next
                lists[min_index] = lists[min_index].next
                min_index, min_now = inf, inf
            else:
                break
        return ans.next

大佬题解:

思路一、

建堆,因为堆适用于每次取出最大或最小,且插入元素的时间复杂度是O(logk),k为堆中元素个数

而每次需要插入的节点为每个链链首中最小的,下一个的道理等同

ListNode.__lt__ = lambda a, b: a.val < b.val  # 让堆可以比较节点大小

class Solution:
    def mergeKLists(self, lists: List[Optional[ListNode]]) -> Optional[ListNode]:
        cur = dummy = ListNode()  # 哨兵节点,作为合并后链表头节点的前一个节点
        h = [head for head in lists if head]  # 初始把所有链表的头节点入堆
        heapify(h)  # 堆化
        while h:  # 循环直到堆为空
            node = heappop(h)  # 剩余节点中的最小节点
            if node.next:  # 下一个节点不为空
                heappush(h, node.next)  # 下一个节点有可能是最小节点,入堆
            cur.next = node  # 合并到新链表中
            cur = cur.next  # 准备合并下一个节点
        return dummy.next  # 哨兵节点的下一个节点就是新链表的头节点

二、递归合并

class Solution:
    # 21. 合并两个有序链表
    def mergeTwoLists(self, list1: Optional[ListNode], list2: Optional[ListNode]) -> Optional[ListNode]:
        cur = dummy = ListNode()  # 用哨兵节点简化代码逻辑
        while list1 and list2:
            if list1.val < list2.val:
                cur.next = list1  # 把 list1 加到新链表中
                list1 = list1.next
            else:  # 注:相等的情况加哪个节点都是可以的
                cur.next = list2  # 把 list2 加到新链表中
                list2 = list2.next
            cur = cur.next
        cur.next = list1 if list1 else list2  # 拼接剩余链表
        return dummy.next

    def mergeKLists(self, lists: List[Optional[ListNode]]) -> Optional[ListNode]:
        m = len(lists)
        if m == 0: return None  # 注意输入的 lists 可能是空的
        if m == 1: return lists[0]  # 无需合并,直接返回
        left = self.mergeKLists(lists[:m // 2])  # 合并左半部分
        right = self.mergeKLists(lists[m // 2:])  # 合并右半部分
        return self.mergeTwoLists(left, right)  # 最后把左半和右半合并

参考来源:作者:灵茶山艾府
链接:https://leetcode.cn/problems/merge-k-sorted-lists/solutions/2384305/liang-chong-fang-fa-zui-xiao-dui-fen-zhi-zbzx/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值