给定一个链表,每个节点包含一个额外增加的随机指针,该指针可以指向链表中的任何节点或空节点。
要求返回这个链表的 深拷贝。
我们用一个由 n 个节点组成的链表来表示输入/输出中的链表。每个节点用一个 [val, random_index] 表示:
val:一个表示 Node.val 的整数。
random_index:随机指针指向的节点索引(范围从 0 到 n-1);如果不指向任何节点,则为 null 。
示例 1:
输入:head = [[7,null],[13,0],[11,4],[10,2],[1,0]]
输出:[[7,null],[13,0],[11,4],[10,2],[1,0]]
链接:https://leetcode.com/problems/copy-list-with-random-pointer/
**解法一:**哈希表法
"""
# Definition for a Node.
class Node:
def __init__(self, x, next=None, random=None):
self.val = int(x)
self.next = next
self.random = random
"""
class Solution(object):
def copyRandomList(self, head):
"""
:type head: Node
:rtype: Node
"""
# hashmap
if not head:
return None
h = {}
p = head
while p:
h[p] = Node(p.val)
p = p.next
p = head
while p:
h[p].next = h.get(p.next)
h[p].random = h.get(p.random)
p = p.next
return h[head]
Time:O(N)
Space: O(N)
**解法二:**原地克隆结点,然后修改指针
"""
# Definition for a Node.
class Node:
def __init__(self, x, next=None, random=None):
self.val = int(x)
self.next = next
self.random = random
"""
class Solution(object):
def copyRandomList(self, head):
"""
:type head: Node
:rtype: Node
"""
if not head:
return None
p = head
# 克隆源结点,将其跟着源节点后
while p:
temp = p.next
p.next = Node(p.val)
p.next.next = temp
p = temp
print(head)
# 修改random指针
p = head
while p:
if p.random:
p.next.random = p.random.next
p = p.next.next
# 将原链表和克隆链表分离
p1 = head
res = p2 = head.next
while p2 and p2.next:
p1.next = p2.next
p2.next = p2.next.next
p1 = p1.next
p2 = p2.next
p1.next = None
return res
Time: O(N)
Space: O(1)