合并两个有序链表(LeetCode No.21)

·  阅读 27

一、题目描述

题目链接:LeetCode 21

二、算法思路

2.1 建模

这题非常简单,作为系列开篇。将两个有序单链表进行合并,本质思路是使用两个逐一偏移指针p1p2对链表l1l2进行元素比对,获取min(p1, p2)元素拼接到新链表(结果链表)上。抽象来看,像拉拉链一样。l1、l2为拉链的左右链,拉取的过程是融合两者元素,形成拉完后的链条。

核心需要:

  1. 两个偏移指针,逐一遍历l1、l2
  2. 对链表结点数据域的比对方法
  3. 一条新的单链表,用于承载结果

2.2 注意事项

  • 新创建的单链表可以使用「虚拟头结点」,也就是 chain 节点。利用虚拟头结点进行占位,可以避免空指针边界异常,降低代码的复杂性。

  • 两条待处理的单链表长度是不一定相等的,需要考虑较长链表多出部分的结点处理。

三、核心代码

/// 合并两个有序单链表, 保持有序(LC21)
/// - Parameters:
///   - l1: 第一个单链表
///   - l2: 第二个单链表
/// - Returns: 合并结果
func mergeTwoLists(l1: SingleLinkNode<Int>, l2: SingleLinkNode<Int>) -> SingleLinkNode<Int> {
    let chain = SingleLinkNode(val: -1)
    var p = chain
    var p1: SingleLinkNode<Int>? = l1
    var p2: SingleLinkNode<Int>? = l2

    while p1 != nil && p2 != nil {
        if p1!.val < p2!.val {
            p.next = p1
            p1 = p1?.next
        } else {
            p.next = p2
            p2 = p2?.next
        }

        if let next = p.next {
            p = next
        }
    }

    if (p1 != nil) {
        p.next = p1
    }

    if (p2 != nil) {
        p.next = p2
    }

    return chain
}
复制代码

本算法系列的所有代码,已同步更新到github.com/Smallfan/Sw…,欢迎 fork。

分类:
iOS
标签:
收藏成功!
已添加到「」, 点击更改