LeetCode之HOT100--023 合并K个升序链表

77 阅读1分钟

这是我参与11月更文挑战的14天,活动详情查看:2021最后一次更文挑战」。

前言

一直都计划学习数据结构与基本算法,但是平时都看一阵停一阵。现在决心坚持下去,我准备从LeetCode的HOT100开始,每天完成1~2道习题,希望通过这种方式养成持续学习的习惯。因为我是做iOS开发的,主要是用Objective-C语言,最近也在学习Swift,所以本系列的题解都将使用swift语言完成,本文更新的是LeetCode中HOT100的第14题023 合并K个升序链表。

题目

给你一个链表数组,每个链表都已经按升序排列。
请你将所有链表合并到一个升序链表中,返回合并后的链表。
示例 1:

输入:lists = [[1,4,5],[1,3,4],[2,6]]
输出:[1,1,2,3,4,4,5,6]
解释:链表数组如下:
[
  1->4->5,
  1->3->4,
  2->6
]
将它们合并到一个有序链表中得到。
1->1->2->3->4->4->5->6

示例 2:

输入:lists = []
输出:[]

示例 3:

输入:lists = [[]]
输出:[]

提示:

1. k == lists.length
2. 0 <= k <= 10^4
3. 0 <= lists[i].length <= 500
4. -10^4 <= lists[i][j] <= 10^4
5. lists[i] 按 升序 排列
6. lists[i].length 的总和不超过 10^4

分析

依次合并
本题是合并 k 个有序链表,我们在之前的文章中刚完成合成两个有序链表的问题 LeetCode之HOT100--021 合并两个有序链表,那么本题的题解就很简单,可以用合并两个有序链表的方法,将 k 个有序链表依次进行合并即可。

  • 优点是空间复杂度只有O(1),时间复杂度为O(n)

创建链表法
我们的目的其实就是将 k 个链表中的所有元素进行排序形成一个新的链表。所以除了上述的依次合并法之外,我们还可以先将所有的元素保存到一个数组中,然后对该数组进行排序,最后将排序后的数组转换成链表结构即可。本题的题解就是使用这种方式完成的。

  • 优点是思路很简单,时间复杂度在于排序的复杂度O(n*logn)
  • 缺点是空间复杂度比较高,需要数组保存所有元素数据没并且所有节点要重新创建

题解

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     public var val: Int
 *     public var next: ListNode?
 *     public init() { self.val = 0; self.next = nil; }
 *     public init(_ val: Int) { self.val = val; self.next = nil; }
 *     public init(_ val: Int, _ next: ListNode?) { self.val = val; self.next = next; }
 * }
 */
//扩展 ListNode,添加通过数组创建链表的方法
extension ListNode {
    //通过数组创建链表的方法
    func CreatList(_ Array: [Int]) -> ListNode? {
        if let val = Array.first {
            self.val = val
        }else{
            return nil
        }
        var cnt = Array.count - 1
        while cnt > 0 {
            let Node = ListNode(Array[cnt])
            Node.next = self.next
            self.next = Node
            cnt -= 1
        }
        return self
    }
}

class KLLC023 {
    func mergeKLists(_ lists: [ListNode?]) -> ListNode? {
        if lists.isEmpty  {
            return nil
        }
        //保存所有的元素
        var result: [Int] = []
        for list in lists {
            var point = list
            while point != nil {
                result.append(point!.val)
                point = point?.next
            }
        }
        //将所有元素进行排序后 创建链表
        return ListNode().CreatList(result.sorted())
    }
    
}