zoukankan      html  css  js  c++  java
  • [LeetCode] 138. Copy List with Random Pointer 拷贝带随机指针的链表

    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.

    这道题的难点在于如何处理随机指针,由于每一个节点都有一个随机指针,这个指针可以为空,也可以指向链表的任意一个节点,如果在生成一个新节点给其随机指针赋值时,都去遍历原链表的话,OJ上肯定会超时。建立一个原节点和新节点的HashMap,给随机指针赋值时查找HashMap,这样可缩短查找时间。

    解法1: HashMap

    解法2: 

    Java:

    public RandomListNode copyRandomList(RandomListNode head) {
    	if (head == null)
    		return null;
    	HashMap<RandomListNode, RandomListNode> map = new HashMap<RandomListNode, RandomListNode>();
    	RandomListNode newHead = new RandomListNode(head.label);
     
    	RandomListNode p = head;
    	RandomListNode q = newHead;
    	map.put(head, newHead);
     
    	p = p.next;
    	while (p != null) {
    		RandomListNode temp = new RandomListNode(p.label);
    		map.put(p, temp);
    		q.next = temp;
    		q = temp;
    		p = p.next;
    	}
     
    	p = head;
    	q = newHead;
    	while (p != null) {
    		if (p.random != null)
    			q.random = map.get(p.random);
    		else
    			q.random = null;
     
    		p = p.next;
    		q = q.next;
    	}
     
    	return newHead;
    }
    

    Java:

    public RandomListNode copyRandomList(RandomListNode head) {
     
    	if (head == null)
    		return null;
     
    	RandomListNode p = head;
     
    	// copy every node and insert to list
    	while (p != null) {
    		RandomListNode copy = new RandomListNode(p.label);
    		copy.next = p.next;
    		p.next = copy;
    		p = copy.next;
    	}
     
    	// copy random pointer for each new node
    	p = head;
    	while (p != null) {
    		if (p.random != null)
    			p.next.random = p.random.next;
    		p = p.next.next;
    	}
     
    	// break list to two
    	p = head;
    	RandomListNode newHead = head.next;
    	while (p != null) {
    		RandomListNode temp = p.next;
    		p.next = temp.next;
    		if (temp.next != null)
    			temp.next = temp.next.next;
    		p = p.next;
    	}
     
    	return newHead;
    }  

    Python:   Time: O(n)  Space: O(n)

    # Definition for singly-linked list with a random pointer.
    class RandomListNode:
        def __init__(self, x):
            self.label = x
            self.next = None
            self.random = None
    
    class Solution2:
        # @param head, a RandomListNode
        # @return a RandomListNode
        def copyRandomList(self, head):
            dummy = RandomListNode(0)
            current, prev, copies = head, dummy, {}
    
            while current:
                copied = RandomListNode(current.label)
                copies[current] = copied
                prev.next = copied
                prev, current = prev.next, current.next
    
            current = head
            while current:
                if current.random:
                    copies[current].random = copies[current.random]
                current = current.next
    
            return dummy.next
    
    
    if __name__ == "__main__":
        head = RandomListNode(1)
        head.next = RandomListNode(2)
        head.random = head.next
        result = Solution().copyRandomList(head)
        print(result.label)
        print(result.next.label)
        print(result.random.label)
    

    Python: Time: O(n)  Space: O(1)

    class Solution:
        # @param head, a RandomListNode
        # @return a RandomListNode
        def copyRandomList(self, head):
            # copy and combine copied list with original list
            current = head
            while current:
                copied = RandomListNode(current.label)
                copied.next = current.next
                current.next = copied
                current = copied.next
    
            # update random node in copied list
            current = head
            while current:
                if current.random:
                    current.next.random = current.random.next
                current = current.next.next
    
            # split copied list from combined one
            dummy = RandomListNode(0)
            copied_current, current = dummy, head
            while current:
                copied_current.next = current.next
                current.next = current.next.next
                copied_current, current = copied_current.next, current.next
            return dummy.next

    C++:

    class Solution {
    public:
        RandomListNode *copyRandomList(RandomListNode *head) {
            if (!head) return NULL;
            RandomListNode *res = new RandomListNode(head->label);
            RandomListNode *node = res;
            RandomListNode *cur = head->next;
            map<RandomListNode*, RandomListNode*> m;
            m[head] = res;
            while (cur) {
                RandomListNode *tmp = new RandomListNode(cur->label);
                node->next = tmp;
                m[cur] = tmp;
                node = node->next;
                cur = cur->next;
            }
            node = res;
            cur = head;
            while (node) {
                node->random = m[cur->random];
                node = node->next;
                cur = cur->next;
            }
            return res;
        }
    };
    

    类似题目:

    [LeetCode] 133. Clone Graph 克隆无向图

    All LeetCode Questions List 题目汇总

      

  • 相关阅读:
    安装go语言开发环境
    【Graph】399. Evaluate Division(Medium)
    【Divide and Conquer】53.Maximum Subarray(easy)
    int数组交并差集
    Git强制覆盖本地文件
    Git手动合并
    [转]关于BETA、RC、ALPHA、Release、GA等版本号的意义
    [置顶] java处理office文档与pdf文件(二)
    [置顶] 左联接数据不统一问题
    将博客搬至CSDN
  • 原文地址:https://www.cnblogs.com/lightwindy/p/8491358.html
Copyright © 2011-2022 走看看