leetcode_138_copy_list_summary 链表知识

LeetCode 138: Copy List with Random Pointer - 深度讲解与讨论总结


🧠 题目描述

给定一个特殊链表,每个节点除了 valnext 外,还有一个 random 指针,指向链表中的任意一个节点或为 None

目标:深拷贝这个链表,返回一个结构完全相同的新链表(值相同,但节点是新对象)。


✅ 方法一:哈希表 + 两次遍历(空间 O(n),逻辑简单)

class Solution:
    def copyRandomList(self, head: 'Optional[Node]') -> 'Optional[Node]':
        if not head:
            return None
        
        old_to_new = {}
        curr = head
        while curr:
            old_to_new[curr] = Node(curr.val)
            curr = curr.next

        curr = head
        while curr:
            old_to_new[curr].next = old_to_new.get(curr.next)
            old_to_new[curr].random = old_to_new.get(curr.random)
            curr = curr.next

        return old_to_new[head]

✅ 方法二:原地插入 + 拆分链表(空间 O(1),推荐)

🌱 思路步骤:

  1. 在每个节点后插入一个新节点(A → A’ → B → B’)
  2. 设置新节点的 random 指针(A'.random = A.random.next
  3. 拆分出两个独立链表(旧链表恢复、新链表独立)
class Solution:
    def copyRandomList(self, head: 'Optional[Node]') -> 'Optional[Node]':
        if not head:
            return None

        # Step 1: 插入新节点
        cur = head
        while cur:
            newNode = Node(cur.val)
            newNode.next = cur.next
            cur.next = newNode
            cur = newNode.next

        # Step 2: 设置 random 指针
        cur = head
        while cur:
            if cur.random:
                cur.next.random = cur.random.next
            cur = cur.next.next

        # Step 3: 拆分链表
        old = head
        new = head.next
        newhead = head.next
        while old:
            old.next = old.next.next
            if new.next:
                new.next = new.next.next
            old = old.next
            new = new.next

        return newhead

🔍 深入解释关键语句

cur.next.random = cur.random.next

  • cur: 当前原节点(如 A)
  • cur.next: 对应的新节点 A’
  • cur.random: 原链表中的 random 目标(如 C)
  • cur.random.next: C 的复制节点 C’

所以:A'.random = C'


🧠 链表指针变量理解

  • curhead 初始时指向同一个对象(引用)
  • cur 向后走,head 不变,可以用 head 重新遍历整个链表
  • 这是链表操作中的典型特性:操作指针移动,头节点保留入口

✅ 指针总结:old、new、new_head 的区别与作用

指针名作用是否会移动最终位置
old遍历原链表✅ 会None
new遍历新链表✅ 会None
new_head记录新链表的头❌ 不会A’(头)

🎯 总结一句话:

利用在原链表中插入复制节点的技巧,节省了额外空间,
通过 “cur.next” 和 “cur.random.next” 达成了精巧的结构复制,
最后再将链表一分为二,新旧链表独立,各不干扰。


以上是我们围绕这道题的全部分析和代码讲解 🙌
你现在对链表的结构操作和引用传递理解已经非常深入了!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值