1669. 合并两个链表

目录

💡【链表题解】删除并替换链表区间节点——合并两个链表(Python详解)

📌 题目描述

🧠 解题思路分析

💬 要点梳理:

🛠 解题方法:Python 实现

🔍 示例说明

📊 时间和空间复杂度分析

🔁 方法对比与扩展

🧪 附:辅助函数(用于测试)

✅ 总结


💡【链表题解】删除并替换链表区间节点——合并两个链表(Python详解)

📌 题目描述

给你两个单链表 list1list2,它们分别包含 n 个和 m 个节点。

请你将 list1 中从下标 ab(包含 ab)的所有节点删除,并将 list2 插入到该位置。

操作后的链表结构如下图所示(蓝色部分是插入后的结构):

list1: 0 → 1 → 2 → 3 → 4 → 5
list2: 1000000 → 1000001 → 1000002
a = 3, b = 4

结果: 0 → 1 → 2 → 1000000 → 1000001 → 1000002 → 5

🧠 解题思路分析

本题主要考察链表节点的删除与连接操作,要求我们精准操作链表中的指针关系,完成以下两个任务:

  1. 删除 list1 中第 a 到第 b 个节点(包含)。
  2. list2 插入到 list1 的删除区域中。

💬 要点梳理:

  • 删除链表节点,关键是找到待删区段的前一个节点后一个节点
  • 插入链表的过程,本质上就是将前半段接到 list2 上,再将 list2 的尾节点接到后半段;
  • 由于链表是单向的,无法“倒着走”,所以我们只能正向遍历来找到我们需要的位置。

🛠 解题方法:Python 实现

首先定义链表节点的数据结构:

class ListNode:
    def __init__(self, val=0, next=None):
        self.val = val
        self.next = next

然后实现题目要求的函数:

class Solution:
    def mergeInBetween(self, list1: ListNode, a: int, b: int, list2: ListNode) -> ListNode:
        # 找到 list1 中下标为 a-1 的节点(即删除区段前一个节点)
        prev = list1
        for _ in range(a - 1):
            prev = prev.next

        # 找到 list1 中下标为 b 的节点的下一个节点
        post = prev
        for _ in range(b - a + 2):
            post = post.next

        # 将 prev.next 指向 list2 的头节点
        prev.next = list2

        # 遍历 list2,找到尾部
        tail = list2
        while tail.next:
            tail = tail.next

        # 将 list2 的尾部接到 post 上
        tail.next = post

        return list1

🔍 示例说明

以如下输入为例:

list1: 0 → 1 → 2 → 3 → 4 → 5
list2: 1000000 → 1000001 → 1000002
a = 3
b = 4

执行过程:

  1. prev 找到的是节点 2(index 2);
  2. post 找到的是节点 5(index 5);
  3. 连接关系变为:
2 → 1000000 → 1000001 → 1000002 → 5

最终完整链表变为:

0 → 1 → 2 → 1000000 → 1000001 → 1000002 → 5

📊 时间和空间复杂度分析

  • 时间复杂度:O(n + m)
    • 遍历到 a-1b+1 需要 O(n)
    • 遍历 list2 找到尾部需要 O(m)
  • 空间复杂度:O(1)
    • 所有操作在原链表结构上完成,没有额外空间分配

🔁 方法对比与扩展

方法

优点

缺点

适用场景

双指针遍历

简洁、直观

多次遍历

中等规模链表操作

拆分重建链表

易于理解

空间复杂度高

教学、调试场景

使用 dummy 节点

处理头部操作更方便

稍显复杂

需要在头部插入或删除时

本题中采用双指针遍历的方式最简洁直接,实战中非常实用。


🧪 附:辅助函数(用于测试)

# 构建链表
def build_list(arr):
    dummy = ListNode(0)
    cur = dummy
    for val in arr:
        cur.next = ListNode(val)
        cur = cur.next
    return dummy.next

# 打印链表
def print_list(head):
    while head:
        print(head.val, end=" → " if head.next else "\n")
        head = head.next

# 测试
list1 = build_list([0, 1, 2, 3, 4, 5])
list2 = build_list([1000000, 1000001, 1000002])
a, b = 3, 4

sol = Solution()
result = sol.mergeInBetween(list1, a, b, list2)
print_list(result)

输出:

0 → 1 → 2 → 1000000 → 1000001 → 1000002 → 5

✅ 总结

这道题是一道非常典型的链表结构题,考察的是对链表节点操作的熟练程度。

关键点在于:

  • 正确找到前置节点 (a-1) 和后继节点 (b+1)
  • 清晰地操作指针连接
  • 防止链表断裂或循环引用
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值