zoukankan      html  css  js  c++  java
  • 刷题——合并K个排序链表

    先看题目

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

    示例:

    输入:
    [
    1->4->5,
    1->3->4,
    2->6
    ]
    输出: 1->1->2->3->4->4->5->6


    拿到题按照规矩,首先先暴力一遍,把拿到的数据全部放进数组sort一下,然后放进一个链表

    ps:太久没有接触链表了,几乎忘完了...写next的时候还在用->next =-=

    # Definition for singly-linked list.
    # class ListNode:
    #     def __init__(self, x):
    #         self.val = x
    #         self.next = None
    
    class Solution:
        def mergeKLists(self, lists: List[ListNode]) -> ListNode:
            self.nodes = []
            head = point = ListNode(0)
            for l in lists:
                while l:
                    self.nodes.append(l.val)
                    l = l.next
            for x in sorted(self.nodes):
                point.next = ListNode(x)
                point = point.next
            return head.next
    

    时间用了224ms

    接下来看看有没有什么省时间的算法

    首先,先试着分析只有两个的链表的时候

    我去LeetCode上面搜了一下,还真有这一题

    https://leetcode-cn.com/problems/merge-two-sorted-lists/solution/he-bing-liang-ge-you-xu-lian-biao-by-leetcode/

    将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。

    示例:

    输入:1->2->4, 1->3->4
    输出:1->1->2->3->4->4


    既然是已经排序好的,那就先比较这两个链表的首个数字,比较出小的next,之后再次进行比较,选小的next一直循环下去

    # Definition for singly-linked list.
    # class ListNode:
    #     def __init__(self, x):
    #         self.val = x
    #         self.next = None
    
    class Solution:
        def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
            head = ListNode(0)
            point = head
            while l1 and l2:
                if l1.val <= l2.val:
                    point.next = l1
                    l1 = l1.next
                else:
                    point.next = l2
                    l2 = l2.next
                point = point.next
            if l1:
                point.next = l1
            else:
                point.next = l2
            return head.next
    

    那么放在K个链表里面,也可以采取这种方式,这里用到了队列这样更加方面

    参考资料:百度优先队列。

    from Queue import PriorityQueue
    class Solution(object):
        def mergeKLists(self, lists):
            """
            :type lists: List[ListNode]
            :rtype: ListNode
            """
            q = PriorityQueue()
            head = point = ListNode(0)
            for l in lists:
                if l:
                    q.put((l.val,l))
            while not q.empty():
                val, node = q.get()
                point.next = ListNode(val)
                point = point.next
                node = node.next
                if node:
                    q.put((node.val, node))
            return head.next
    

    花费的时间192ms,比暴力的时间稍微快一点

    想不出什么办法,只能去参考题解了,连接在下面。
    链接:https://leetcode-cn.com/problems/two-sum/solution/he-bing-kge-pai-xu-lian-biao-by-leetcode/

    这个算法是两两合并的算法进行了优化。

    不得不说,我做了那到合并两个链表的题目二也没有想过通过一轮一轮的方法来做这道题,而是直接把合并两个链表的方法(不听取最小的放在最后的链表里面)直接用了=-=

    只能说太死脑筋啦,今天学习到了,代码也贴在下面:

    # Definition for singly-linked list.
    # class ListNode(object):
    #     def __init__(self, x):
    #         self.val = x
    #         self.next = None
    # Definition for singly-linked list.
    # class ListNode:
    #     def __init__(self, x):
    #         self.val = x
    #         self.next = None
    from Queue import PriorityQueue
    class Solution(object):
        def mergeKLists(self, lists):
            """
            :type lists: List[ListNode]
            :rtype: ListNode
            """
            len_of_lists = len(lists)
            if len_of_lists == 0:
                return 
            len_of_next = 1
            while len_of_next < len_of_lists:
                for i in range(0, len_of_lists - len_of_next, len_of_next*2):
                    lists[i] = self.merge2Lists(lists[i], lists[i+len_of_next])
                len_of_next *= 2
            return lists[0]
        def merge2Lists(self, l1, l2):
            head = point = ListNode(0)
            while l1 and l2:
                if l1.val <= l2.val:
                    point.next = ListNode(l1.val)
                    l1 = l1.next
                else:
                    point.next = ListNode(l2.val)
                    l2 = l2.next
                point = point.next
            if l1:
                point.next = l1
            else:
                point.next = l2
            return head.next
    

    这道题用了三种方法,还进行了优化,感觉学到了很多,以后想问题的时候格局要大一点咯

  • 相关阅读:
    keepalived
    设置Suse linux 用户远程登录超时时间
    启用Linux云平台oracle数据库实口令复杂性函数:PASSWORD_VERIFY_FUNCTION=NULL
    将tomcat7解压版注册为windows系统服务
    linux 在后台运行数据库导入导出命令
    suse enterprise Linux 11上配置 oracle11g和tomcat开机自启动
    Linux下的Tomcat JVM 调优
    oracle 11g 常用命令
    如何运行jnlp文件
    查询oracle 数据库 SQL语句执行情况
  • 原文地址:https://www.cnblogs.com/fanwenkeer/p/11270796.html
Copyright © 2011-2022 走看看