JAVA程序設計:複製帶隨機指針的鏈表(LeetCode:138)

給定一個鏈表,每個節點包含一個額外增加的隨機指針,該指針可以指向鏈表中的任何節點或空節點。

要求返回這個鏈表的深拷貝。 

 

示例:

輸入:
{"$id":"1","next":{"$id":"2","next":null,"random":{"$ref":"2"},"val":2},"random":{"$ref":"2"},"val":1}

解釋:
節點 1 的值是 1,它的下一個指針和隨機指針都指向節點 2 。
節點 2 的值是 2,它的下一個指針指向 null,隨機指針指向它自己。
 

提示:

你必須返回給定頭的拷貝作爲對克隆列表的引用。

 

方法一:回朔。 如果沒有隨機指針,呢就是一條鏈進行深拷貝即可,但是因爲隨機指針的存在,鏈表就成爲了一個有向圖,因此我們需要按照圖的遍歷方式進行深拷貝,因爲隨機指針的隨機性,使得這個圖可能存在環,因此我們需要標記我們已經遍歷過的節點,以防形成死循環。

class Node {
    public int val;
    public Node next;
    public Node random;

    public Node() {}

    public Node(int _val,Node _next,Node _random) {
        val = _val;
        next = _next;
        random = _random;
    }
};

class Solution {
	
	HashMap<Node,Node> visitedNode=new HashMap<>();
	
    public Node copyRandomList(Node head) {
        
    	if(head==null)
    		return null;
    	
    	if(visitedNode.containsKey(head))
    		return visitedNode.get(head);
    	
    	Node node=new Node(head.val,null,null);
    	
    	visitedNode.put(head, node);
    	
    	node.next=copyRandomList(head.next);
    	node.random=copyRandomList(head.random);
    	
    	return node;
    }
}

方法二:迭代(O(n)的空間複雜度)

class Node {
    public int val;
    public Node next;
    public Node random;

    public Node() {}

    public Node(int _val,Node _next,Node _random) {
        val = _val;
        next = _next;
        random = _random;
    }
};

class Solution {
	
	HashMap<Node,Node> visitedNode=new HashMap<>();
	
    public Node copyRandomList(Node head) {
        
    	if(head==null)
    		return null;
    	
    	Node oldnode=head;
    	Node newnode=new Node(oldnode.val,null,null);
    	visitedNode.put(oldnode, newnode);
    	
    	while(oldnode!=null)
    	{
    		newnode.random=getCloneNode(oldnode.random);
    		newnode.next=getCloneNode(oldnode.next);
    		
    		oldnode=oldnode.next;
    		newnode=newnode.next;
    	}
    	return visitedNode.get(head);
    }
    
    private Node getCloneNode(Node node)
    {
    	if(node==null)
    		return null;
    	
    	if(visitedNode.containsKey(node))
    		return visitedNode.get(node);
    	else
    	{
    		visitedNode.put(node, new Node(node.val,null,null));
    		return visitedNode.get(node);
    	}
    }
}

方法三:迭代(O(1)的空間複雜度)

方法參考題解:138題解的方法三

class Solution {
	
	HashMap<Node,Node> visitedNode=new HashMap<>();
	
    public Node copyRandomList(Node head) {
        
    	if(head==null)
    		return null;
    	
    	Node ptr=head;
    	
    	while(ptr!=null)
    	{
    		Node newnode=new Node(ptr.val,null,null);
    		
    		newnode.next=ptr.next;
    		ptr.next=newnode;
    		ptr=newnode.next;
    		
    	}
    	
    	ptr=head;
    	while(ptr!=null)
    	{
    		ptr.next.random=(ptr.random!=null)?ptr.random.next:null;
    		ptr=ptr.next.next;
    	}
    	
    	Node ptr_old_list=head;
    	Node ptr_new_list=head.next;
    	Node head_old=head.next;
    	while(ptr_old_list!=null)
    	{
    		ptr_old_list.next=ptr_old_list.next.next;
    		ptr_new_list.next=ptr_new_list.next!=null?ptr_new_list.next.next:null;
    		ptr_old_list=ptr_old_list.next;
    		ptr_new_list=ptr_new_list.next;
    	}
    	
    	return head_old;
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章