解法
- 第一步:复制链表的所有节点,并放在对应节点之后形成一个长链表。这样的好处是在没有使用额外空间的情况下,在O(1)时间内找到random指针指向的节点
- 第二步: 复制所有random指针
- 第三步:将长链表的偶数部分与奇数部分拆分,返回偶数部分
1
2
3
/*
// 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 {
public Node copyRandomList(Node head) {
cloneNodes(head);
connectRandomNodes(head);
return reconnectNodes(head);
}
//第一步:复制链表的所有节点N的副本N',将N'放在N的后面串成一串
private void cloneNodes(Node head){
Node pNode = head;
while(pNode != null){
Node node = new Node(pNode.val);
node.next = pNode.next;
pNode.next = node;
pNode = node.next;
}
}
//第二步:复制random指针,原链表上N的random指针指向S,则复制链表上的N’指向S’
private void connectRandomNodes(Node head){
Node pNode = head;
while(pNode != null){
Node pCloned = pNode.next;
if(pNode.random != null){
pCloned.random = pNode.random.next;
}
pNode = pCloned.next;
}
}
//第三步:将长链表拆成两个链表,奇数位置用next指针连接起来就是原链表,偶数位置连接起来就是复制链表
private Node reconnectNodes(Node head){
Node pNode = head;
Node pCloneHead = null;
Node pCloneNode = null;
if(pNode != null){
pCloneHead = pCloneNode = pNode.next;
pNode.next = pCloneNode.next;
pNode = pNode.next;
}
while(pNode != null){
pCloneNode.next = pNode.next;
pCloneNode = pCloneNode.next;
pNode.next = pCloneNode.next;
pNode = pNode.next;
}
return pCloneHead;
}
}