2014年5月6日星期二

Loop Solution - Copy List with Random Pointer - watch reference

Case one: single direction

/**
 * Definition for singly-linked list with a random pointer.
 * class RandomListNode {
 *     int label;
 *     RandomListNode next, random;
 *     RandomListNode(int x) { this.label = x; }
 * };
 */
public class Solution {
    public RandomListNode copyRandomList(RandomListNode head) {
        if(head == null){
            return null;
        }
        Map<Integer, RandomListNode> nodes = new HashMap<Integer, RandomListNode>();
       
        RandomListNode newHead = new RandomListNode(head.label);
        RandomListNode newNode = newHead;
        RandomListNode node = head;
        while(node != null){
            if(node.next != null){
                if(nodes.containsKey(node.next.label)){
                    newNode.next = nodes.get(node.next.label);
                }else{
                    RandomListNode newNext = new RandomListNode(node.next.label);
                    newNode.next = newNext;
                    nodes.put(node.next.label, newNext);
                }
            }else{
                newNode.next = null;
            }
           
            if(node.random == null){
                newNode.random = null;
            }else{
                if(nodes.containsKey(node.random.label)){
                    newNode.random = nodes.get(node.random.label);
                }else{
                    RandomListNode newRandom = new RandomListNode(node.random.label);
                    newNode.random = newRandom;
                    nodes.put(node.random.label, newRandom);
                }
            }
            node = node.next;
            newNode = newNode.next;
        }
        return newHead;
    }
}

Case two: two directions

/*
Extended doubly linked list:

           ------           ------           ------           ------
           |    | --------> |    | --------> |    | --------> |    | ---> NULL
 NULL <--- | 2  | <-------- | 7  | <-------- | 1  | <-------- | 4  |
           ------           ------           ------           ------
            | ^                |              ^  |             |  ^
            | |----------------|              |  |             |  |
            |                                 |  NULL          ----
            ----------------------------------|

*/

public class Node
{
   private Node previous;
   private Node next;
   private int value;

   public Node(int v)
   {
      value = v;
   }

   public Node getPrevious() { return previous; }
   public void setPrevious(Node prevNode)
   {
      previous = prevNode;
   }

   public Node getNext() { return next; }
   public void SetNext(Node nextNode)
   {
      next = nextNode;
   }
 
   public Node getRandom() { return random; }
   public void setRandom(Node randomNode)
   {
      random = randomNode;
   }

   public int getValue() { return value; }
}



// MakeCopy takes a Node object that is the first node in the original list (the head node).
// The function makes a deep copy of the list (new object for each node) and returns the new head node
private Node MakeCopy(Node head)
{
  if(head == null){
      return null;
  }
 
  Map<Integer, Node> process = new HashMap<Integer, Node>();
 
  Node preHead = new Node(Integer.MIN_VALUE); //Node returnHead = new  Node(head.getValue()); //watch reference
  Node node = new Node(head.getValue());  //This definitely can be refactored into while
  preHead.setNext(node);
  node.setPrevious(null);
  process.put(node.getValue(), node);
 
  setRandomNode(node, head, process);
 
  Node loop = head.getNext();
  while(loop != null){
      Node newNode = null;// new Node(loop.getValue());
      if(process.containsKey(loop.getValue())){
          newNode = process.get(loop.getValue());
      }else{
          newNode = new Node(loop.getValue());
          process.put(loop.getValue(), newNode);
      }
      node.setNext(newNode);
      newNode.setPrevious(node);
      setRandomNode(newNode, loop, process);
      node = newNode;
      loop = loop.getNext();
  }
  node.setNext(null);
 
  Node resHead = preHead.getNext();
  preHead.setNext(null); //just for reference remove... actually doesnt make too much difference
  process = null; // ...
  return resHead;  
}


private void setRandomNode(Node newNode, Node oldNode, Map<Integer, Node> process){
    Node newRandom = null;
    if(oldNode.getRandom() != null){
        if(process.containsKey(oldNode.getRandom().getValue())){
          newRandom = process.get(oldNode.getRandom().getValue());
      }else{
          newRandom = new Node(oldNode.getRandom().getValue());
          process.put(oldNode.getRandom().getValue(), newRandom); //Had a bug before interview complete
      }
    }
   // else{
   //     newNode.setRandom(null);
   // }
    newNode.setRandom(newRandom);
}

没有评论: