import java.util.*;
/**
* A linked list is given such that each node contains an additional random
* pointer which could point to any node in the list or null.
*
* Return a deep copy of the list.
*
* Tags: Hashtable, Linkedlist
*/
class CopyListWithRandomP {
public static void main(String[] args) {
}
/**
* Use a hashmap to store map between original node and copy node
*/
public RandomListNode copyRandomList(RandomListNode head) {
Map<RandomListNode, RandomListNode> map = new HashMap<RandomListNode, RandomListNode>();
return helper(head, map);
}
/**
* Get copy node from map
*/
public RandomListNode helper(RandomListNode node, Map<RandomListNode, RandomListNode> map) {
if (node == null) return null;
if (map.containsKey(node)) return map.get(node); // return copy
RandomListNode res = new RandomListNode(node.label);
map.put(node, res); // build map
res.next = helper(node.next, map); // build next
res.random = helper(node.random, map); // build copy
return res;
}
/**
* Insert a same node after current node
* Then split into two lists
*/
public RandomListNode copyRandomList2(RandomListNode head) {
if (head == null) return head;
RandomListNode p1 = head;
while (p1 != null) {
RandomListNode copy = new RandomListNode(p1.label);
copy.next = p1.next;
p1.next = copy;
p1 = p1.next.next;
}
p1 = head;
while (p1 != null && p1.next != null) {
if (p1.random != null) p1.next.random = p1.random.next;
p1 = p1.next.next;
}
// split lists
p1 = head;
RandomListNode copy = p1.next;
RandomListNode dummy = copy;
while (copy != null && p1 != null) {
p1.next = p1.next.next;
if (copy.next == null) break;
copy.next = copy.next.next;
copy = copy.next;
p1 = p1.next;
}
return dummy;
}
/**
* Build a new list and connect original and new node together
*/
public RandomListNode copyRandomList3(RandomListNode haed) {
}
class RandomListNode {
int label;
RandomListNode next, random;
RandomListNode(int x) { this.label = x; }
};
}