题目描述
输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)
解题思路
- 遍历整个链表,在第n个节点与第n+1个节点中间,插入一个与第n个节点值相同的节点。建立一个node与nodeCopy的映射关系(node.next == nodeCopy)
- 遍历链表,可以通过node得知random,然后将这个random对应的randomCopy(random.next)赋给nodeCopy.random,即node.next.random = node.random.next
- 将copy的节点拆分出来,得到新的链表
代码实现
/*
// 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) {
if (head == null) {
return null;
}
copyNode(head);
copyRandomPointer(head);
return splitList(head);
}
private void copyNode(Node head) {
Node curOld = head;
while (curOld != null) {
Node tmp = curOld.next;
curOld.next = new Node(curOld.val);
curOld.next.next = tmp;
curOld = tmp;
}
}
private void copyRandomPointer(Node head) {
Node curOld = head;
while (curOld != null) {
curOld.next.random = curOld.random == null ? curOld.random : curOld.random.next;
curOld = curOld.next.next;
}
}
private Node splitList(Node head) {
Node curOld = head;
Node newHead = head.next;
Node curNew = head.next;
while (curNew.next != null) {
curOld.next = curNew.next;
curNew.next = curNew.next.next;
curNew = curNew.next;
curOld = curOld.next;
}
curOld.next = null;
return newHead;
}
}