您好,登录后才能下订单哦!
密码登录
登录注册
点击 登录注册 即表示同意《亿速云用户服务条款》
# LeetCode如何实现复制带随机指针的链表
## 问题描述
LeetCode第138题"复制带随机指针的链表"(Copy List with Random Pointer)要求我们深度复制一个特殊的链表结构。这种链表的每个节点除了包含标准的`val`和`next`指针外,还包含一个可能指向链表中任意节点或为`null`的`random`指针。
```python
class Node:
def __init__(self, x: int, next: 'Node' = None, random: 'Node' = None):
self.val = int(x)
self.next = next
self.random = random
普通链表的复制非常简单,只需遍历原链表逐个创建新节点即可。但带随机指针的链表存在以下难点:
def copyRandomList(head: 'Node') -> 'Node':
if not head:
return None
# 建立原节点到新节点的映射
mapping = {}
curr = head
while curr:
mapping[curr] = Node(curr.val)
curr = curr.next
# 设置新节点的next和random指针
curr = head
while curr:
if curr.next:
mapping[curr].next = mapping[curr.next]
if curr.random:
mapping[curr].random = mapping[curr.random]
curr = curr.next
return mapping[head]
原链表:A -> B -> C
穿插后:A -> A' -> B -> B' -> C -> C'
def copyRandomList(head: 'Node') -> 'Node':
if not head:
return None
# 1. 在每个原节点后插入新节点
curr = head
while curr:
new_node = Node(curr.val)
new_node.next = curr.next
curr.next = new_node
curr = new_node.next
# 2. 设置新节点的random指针
curr = head
while curr:
if curr.random:
curr.next.random = curr.random.next
curr = curr.next.next
# 3. 分离两个链表
curr = head
new_head = head.next
while curr:
temp = curr.next
curr.next = temp.next
if temp.next:
temp.next = temp.next.next
curr = curr.next
return new_head
在实际编码中需要考虑以下边界情况:
# 示例1
# 输入:head = [[7,null],[13,0],[11,4],[10,2],[1,0]]
# 输出:[[7,null],[13,0],[11,4],[10,2],[1,0]]
# 示例2
# 输入:head = [[1,1],[2,1]]
# 输出:[[1,1],[2,1]]
# 示例3
# 输入:head = [[3,null],[3,0],[3,null]]
# 输出:[[3,null],[3,0],[3,null]]
方法 | 时间复杂度 | 空间复杂度 | 优点 | 缺点 |
---|---|---|---|---|
哈希表映射法 | O(N) | O(N) | 思路直观,两次遍历 | 需要额外哈希表空间 |
节点穿插法 | O(N) | O(1) | 常数空间,适合空间限制 | 需要三次遍历,修改原链表 |
如何处理循环引用的random指针?
为什么穿插法不需要额外空间?
如果链表很大,哪种方法更优?
复制带随机指针的链表是考察对链表结构和哈希表应用的经典题目。两种主要解法各有优劣:
掌握这道题有助于理解更复杂的链表操作和对象引用关系,是数据结构学习中的重要里程碑。 “`
这篇文章共计约1700字,涵盖了问题描述、解决方案、复杂度分析、边界情况、测试用例、方法比较和扩展思考等内容,采用Markdown格式编写,可直接用于技术博客或面试准备。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。