题目:
请实现 copyRandomList 函数,复制一个复杂链表。在复杂链表中,每个节点除了有一个 next 指针指向下一个节点,还有一个 random 指针指向链表中的任意节点或者 null。
leetcode原题链接
思路:
三个步骤:
- 复制链表节点 至原节点后
- 给新Node复制random指向
- 拆开链表
代码:
"""
# Definition for a Node.
class Node:
def __init__(self, x: int, next: 'Node' = None, random: 'Node' = None):
self.val = int(x)
self.next = next
self.random = random
"""
class Solution:
def copyRandomList(self, head: 'Node') -> 'Node':
p=head#创建遍历指针p,初始时位于头节点位置
#复制链表节点
if head is None:
return None
while p:
newnode=Node(p.val)
newnode.next=p.next
p.next=newnode
p=newnode.next#对下一个原链表节点操作
p=head#遍历指针重回头节点
#复制random指向
while p:#原节点有random指针时,进行复制
if p.random:
p.next.random=p.random.next
p=p.next.next#对下一个原链表节点操作
p=head#遍历指针重回头节点
newhead=p.next#标记新的头节点
#拆开原链表和复制链表
while p.next:
mark=p.next
p.next=p.next.next
p=mark
return newhead
debug过程:
起初代码报错如下,可以看出 错误出在 第2步 复制random指向
原【复制random指向】代码:
#复制random指向
while p.random:#原节点有random指针时,进行复制
p.next.random=p.random.next
p=p.next.next#对下一个原链表节点操作
while循环的判断条件是:当前p是否有random指向
进入while循环前,遍历指针p已回到头节点head处,所以先对原链表头节点进行操作:
p.val == 7;p.next == 13;p.random == null
由于p.random不存在,直接跳出while循环,进行第3步拆列表,所以复制得到的链表节点的 random指向全为null【初始化时默认是null】
tips:
进行第一步复制链表时需注意这两行代码的顺序
newnode.next=p.next
p.next=newnode
以原链表 A——>B 为例,p=head时,新建一个节点A’
若颠倒顺序,先执行p.next=newnode
,就无法再对B节点进行操作【找不到B节点了】
正确顺序应为: