题目描述:
请实现 copyRandomList 函数,复制一个复杂链表。在复杂链表中,每个节点除了有一个 next 指针指向下一个节点,还有一个 random 指针指向链表中的任意节点或者 null。
方法一:HashMap复制
分2步走:
-
把所有的结点放入map中;
-
处理random指针方向。
参考代码:
public Node copyRandomList(Node head) {
if(head == null)return head;
Map<Node, Node> map = new HashMap<>();
Node curr = head;
//1.将所有的结点放入map中
while(curr!= null){
map.put(curr, new Node(curr.val));
curr = curr.next;
}
//2.处理random
curr = head;
while(curr != null){
map.get(curr).random = map.get(curr.random);//特别注意:处理random指针
map.get(curr).next = map.get(curr.next);//特别注意:连接起来
curr = curr.next;
}
return map.get(head);
}
方法2:
- 先在每个结点后面复制一个结点,如下:
1 -> 2 -> 3;复制后结点为
1 -> 1 -> 2 -> 2 -> 3 -> 3;
-
处理random指针;
-
只将复制的结点连接起来,即去掉原来的所有结点,只返回复制的结点。
参考代码:
public Node copyRandomList(Node head) {
if(head == null)return head;
//1.在每个结点后面复制一个和原来结点值相同的结点
Node curr = head;
while(curr != null){
Node node = new Node(curr.val);//复制一个结点
node.next = curr.next;
curr.next = node;
curr = curr.next.next;
}
//2. 处理复制后的结点的random指针
curr = head;
while(curr != null){
if(curr.random!= null)curr.next.random = curr.random.next;//特别注意:这里要跳过复制的结点,所以右边为curr.random.next
curr = curr.next.next;//跳过复制的结点
}
//3. 删除原来的所有结点,只保留复制的结点,返回头结点
Node copyHead = head.next;
curr = head;
Node t;
while(curr != null){
t = curr.next;
curr.next = t.next;
if(t.next != null)t.next = t.next.next;
curr = curr.next;
t = t.next;
}
return copyHead ;
}
(完)