A linked list of length n is given such that each node contains an additional random pointer, which could point to any node in the list, or null.
Construct a deep copy of the list. The deep copy should consist of exactly n brand new nodes, where each new node has its value set to the value of its corresponding original node. Both the next and random pointer of the new nodes should point to new nodes in the copied list such that the pointers in the original list and copied list represent the same list state. None of the pointers in the new list should point to nodes in the original list.
For example, if there are two nodes X and Y in the original list, where X.random --> Y, then for the corresponding two nodes x and y in the copied list, x.random --> y.
Return the head of the copied linked list.
The linked list is represented in the input/output as a list of n nodes. Each node is represented as a pair of [val, random_index] where:
val: an integer representing Node.val
random_index: the index of the node (range from 0 to n-1) that the random pointer points to, or null if it does not point to any node.
Your code will only be given the head of the original linked list.
该题是深copy一个带有random指针的单向链表。
思路:
如果一个单向链表不带有random指针,正常就是不断创建新的node,一步一步到tail即可。
多一个random指针会有什么影响呢?比如刚创建到第2个node,random却指向第4个node,这时第4个node还没有创建出来;或者已经创建到了第6个node,而random却指向第1个,那怎么能确定第1个是已经存在的node还是需要重新创建呢。
你可能会说我用一个HashSet保存已经创建的节点,不就知道是不是已经存在了。但是创建新节点的时候我只知道节点的值,并不知道random指针指向的node,为什么呢,因为random指向的node可能还没有创建出来。后面一旦修改了random指针,node就不一样了还怎么去找是不是已经存在。
但是可以确定的是,已经给的head指向的链表是确定的,中间不会再变了,可以通过head链表的节点来找到深copy出来的新节点。那么这就需要建立一一映射,一个head节点(key)对应一个新copy出来的节点(value)。
可以按照没有random的步骤,head一步一步向右走,走一步创建一个新节点(深copy),修改它的next节点和random节点(存在就直接指,不存在创建新的)。
public Node copyRandomList(Node head) {
if(head == null) return head;
HashMap<Node, Node> pair = new HashMap<>();
Node newHead = new Node(head.val);
pair.put(head, newHead);
Node tmp = newHead;
while(head != null) {
if(head.next != null) {
Node node = new Node(head.next.val);
if(!pair.containsKey(head.next)) {
pair.put(head.next, node);
tmp.next = node;
} else {
tmp.next = pair.get(head.next);
}
}
if(head.random != null) {
Node random = new Node(head.random.val);
if(!pair.containsKey(head.random)){
pair.put(head.random, random);
tmp.random = random;
} else {
tmp.random = pair.get(head.random);
}
}
head = head.next;
tmp = tmp.next;
}
return newHead;
}