[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 题目汇总

  

posted @ 2018-03-02 08:28  轻风舞动  阅读(431)  评论(0编辑  收藏  举报