[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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
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)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# 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)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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++:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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 @   轻风舞动  阅读(435)  评论(0编辑  收藏  举报
努力加载评论中...
点击右上角即可分享
微信分享提示