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