合并k个有序链表

题目:

合并k个有序链表,并将结果用一个有序链表输出

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

思路:

假设k个链表的总元素数目为n。首先想到两两合并列表,在序列1和2合并,3和4合并,依次类推。直到合并的只剩一个链表。这种操作的时间复杂度为O(nlog(k)),空间复杂度为O(1)。python代码如下:

class Solution(object):
    def mergeKLists(self, lists):
        if not lists:
            return None
        while len(lists) > 1:
            tmp_node = self.mergeTwoLists(lists.pop(0), lists.pop(0))
            lists.append(tmp_node)
        return lists[0]

    def mergeTwoLists(self, p1, p2):
        new_head = ListNode(-1)
        tail = new_head
        while p1 is not None and p2 is not None:
            if p1.val <= p2.val:
                tail.next, tail = p1, p1
                p1 = p1.next
            else:
                tail.next, tail = p2, p2
                p2 = p2.next
        if p1 is None:
            tail.next = p2
        elif p2 is None:
            tail.next = p1
        return new_head.next

注意到在mergeTwoLists()中使用了循环进行合并。当节点数量n大于1000时,使用循环合并比较有效。因为python默认限制函数迭代次数为1000,用迭代的方法合并两个链表,节点数多了就会报错。

还可以同时合并所有列表,这中间需要比较这k个链表的头结点哪个最小。直接比较效率低,想到构建辅助数组,用最大堆来帮助比较。这样做的时间复杂度也是O(nlog(k)),空间复杂度为O(k)。同时注意到某些链表合并完后,辅助数组的长度减小,单次查找速度复杂度会小于log(k)。因此这种用最小堆合并的方式速度会比二分合并快一些。实际上在LeetCode23. Merge k Sorted Lists的测试用例上跑的时候,两种方法花的时间分别是165ms,103ms。

import heapq
class Solution(object):
    def mergeKLists(self, lists):
        head = ListNode(-1)
        current = head
        heap = []
        for node in lists:
            if node:
                heap.append((node.val, node))
        heapq.heapify(heap)
        while heap:
            _, ref = heapq.heappop(heap)
            current.next = ref
            current = current.next
            if ref.next:
                heapq.heappush(heap, (ref.next.val, ref.next))
        return head.next

原文地址:https://www.cnblogs.com/plank/p/9144288.html

时间: 2024-10-08 01:44:51

合并k个有序链表的相关文章

[LeetCode] 23. Merge k Sorted Lists 合并k个有序链表

Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. 与21. Merge Two Sorted Lists的拓展,这道题要合并k个有序链表,还是可以两两合并. 类似题目: [LeetCode] 21. Merge Two Sorted Lists 合并有序链表 原文地址:https://www.cnblogs.com/lightwindy/p/8512

leetcode python 012 hard 合并k个有序链表

#[LeetCode] Merge k Sorted Lists 合并k个有序链表(升序) import numpy as npimport time class Node(object):    def __init__(self,n,next_node=None):        self.data=n        self.next=next_node    class linklist(object):    def __init__(self):        self.head=N

经典算法——合并K个有序链表

一.题目要求: 将K个有序链表合并为一个有序链表 二.实现方法: 方法一:利用最小堆方法 用一个大小为K的最小堆(用优先队列+自定义降序实现)(优先队列就是大顶堆,队头元素最大,自定义为降序后,就变成小顶堆,队头元素最小),先把K个链表的头结点放入堆中,每次取堆顶元素,然后将堆顶元素所在链表的下一个结点加入堆中. 整体测试代码: #include <vector> #include <iostream> #include<queue> #include<set&g

leetcode 23 合并 k 个有序链表

问题描述 * leetcode 23,  Merge k Sorted Lists 解题思路 合并2个有序链表的进阶版,很容易想到,利用分治进行处理. 把个数大于2的集合 两两划分处理,最后再做最后一步的处理. 1 public class Solution { 2 public ListNode mergeKLists(ListNode[] lists) { 3 if (lists.length==0 || lists==null) { return null; } 4 return merg

23. Merge k Sorted Lists 合并K个有序链表

这道题是21题合并2个有序链表的升级版本,看了许多解题思路: A:直接暴力解锁,全部放进一个堆,然后依次吐出来: B:利用21题的算法,循环一次做两两合并,这样就得到结果:但是时间复杂度有点差: C:利用归并排序思想,进行分治:其实就是利用递归,牺牲空间,提升时间效率: 存在的问题是:看过了许多解答后发现,大家基于的给定数据类型是 List<ListNode>/ArrayList<ListNode>,然后,现在系统更新了,给的数据类型是 ListNode[] lists,所以,我现

p122 合并 K 个有序链表(leetcode 23)

一:解题思路 方法一:之前做过一道合并2个链表的题目,那么第一种方法就是将数组中的链表两两合并,得到最后的结果.Time:O(k*n),Space:O(1) 方法二:采用分治法,两两合拼.不断递归,最后只剩下一个链表.Time:O(n*log(k)),Space:O(log(k)) 二:完整代码示例 (C++版和Java版) 方法一C++: class Solution { private: ListNode* mergeTwoSortedLists(ListNode* l1, ListNode

23. 合并K个排序链表

知乎ID: 码蹄疾 码蹄疾,毕业于哈尔滨工业大学. 小米广告第三代广告引擎的设计者.开发者: 负责小米应用商店.日历.开屏广告业务线研发:主导小米广告引擎多个模块重构: 关注推荐.搜索.广告领域相关知识; 题目 合并 k 个排序链表,返回合并后的排序链表.请分析和描述算法的复杂度.示例:输入:[ 1->4->5, 1->3->4, 2->6]输出: 1->1->2->3->4->4->5->6 分析 前面已经做过两个有序链表的合并,只

LeetCode 21. 合并两个有序链表(Merge Two Sorted Lists)

21. 合并两个有序链表 21. Merge Two Sorted Lists 题目描述 将两个有序链表合并为一个新的有序链表并返回.新链表是通过拼接给定的两个链表的所有节点组成的. LeetCode21. Merge Two Sorted Lists 示例: 输入: 1->2->4, 1->3->4 输出: 1->1->2->3->4->4 Java 实现 ListNode 类 class ListNode { int val; ListNode n

LeetCode 23. 合并K个排序链表(Merge Two Sorted Lists)

23. 合并K个排序链表 23. Merge k Sorted Lists 题目描述 合并 k 个排序链表,返回合并后的排序链表.请分析和描述算法的复杂度. LeetCode23. Merge k Sorted Lists困难 示例: 输入: [ ??1->4->5, ??1->3->4, ??2->6] 输出: 1->1->2->3->4->4->5->6 Java 实现 public class ListNode { int va