题目描述
给定一个链表,每个节点包含一个额外增加的随机指针,该指针可以指向链表中的任何节点或空节点。
要求返回这个链表的 深拷贝。
我们用一个由 n
个节点组成的链表来表示输入/输出中的链表。每个节点用一个 [val, random_index]
表示:
val
:一个表示Node.val
的整数。random_index
:随机指针指向的节点索引(范围从0
到n-1
);如果不指向任何节点,则为null
。
样例
输入:head = [[7,null],[13,0],[11,4],[10,2],[1,0]]
输出:[[7,null],[13,0],[11,4],[10,2],[1,0]]
输入:head = [[1,1],[2,1]]
输出:[[1,1],[2,1]]
输入:head = [[3,null],[3,0],[3,null]]
输出:[[3,null],[3,0],[3,null]]
输入:head = []
输出:[]
解释:给定的链表为空(空指针),因此返回 null。
提示:
-10000 <= Node.val <= 10000
Node.random
为空(null
)或指向链表中的节点。- 节点数目不超过
1000
。
算法分析
- 1、复制所有的点
用哈希表存储原来的点 -> 复制后的点
,通过遍历整个链表找到所有的点,并把该点进行复制,存入哈希表中 - 2、复制所有的边
枚举整个哈希表,key
表示原来的点,value
表示复制后的点,- 找到
key
的next
的点,并找到next
对应的复制点,将该复制点赋值到value.next
中, - 找到
key
的random
的点,并找到random
对应的复制点,将该复制点赋值到value.random
中
- 找到
时间复杂度 $O(n)$
Java 代码
/*
// Definition for a Node.
class Node {
int val;
Node next;
Node random;
public Node(int val) {
this.val = val;
this.next = null;
this.random = null;
}
}
*/
class Solution {
static HashMap<Node, Node> map = new HashMap<Node, Node>();
public Node copyRandomList(Node head) {
//将点存入到哈希表中
Node p = head;
while(p != null)
{
map.put(p, new Node(p.val));
p = p.next;
}
//存边
for(Map.Entry<Node, Node> entry : map.entrySet())
{
Node a = entry.getKey();
Node b = entry.getValue();
b.next = map.get(a.next);
b.random = map.get(a.random);
}
return map.get(head);
}
}