Copy List with Random Pointer

update Jul,26 2017 15:14

LintCodearrow-up-right

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.

Challenge Could you solve it with O(1) space?

Basic Idea:

这道题就是说这个链表除了next指针还有一个指针叫做random,可以指向其他任何node,求这个链表的deep copy。

两种思路: 1. 利用图的deep copy的做法,先用一个hashmap复制所有的node,再利用map中的新旧node一一对应关系复制random指针(就相当于图里面的edge),很简单,O(n)空间。 2. 利用链表next一路向后的性质,我们可以构造一个新旧node交替的大链表(old1->new1->old2->new2->old3->new3...),构造成功之后再traverse一遍搞定newnode们的random指针,然后把他们分开即可。

Java Code:

方法1:

    /**
     * Definition for singly-linked list with a random pointer.
     * class RandomListNode {
     *     int label;
     *     RandomListNode next, random;
     *     RandomListNode(int x) { this.label = x; }
     * };
     */
    public class Solution {
        /**
         * @param head: The head of linked list with a random pointer.
         * @return: A new head of a deep copy of the list.
         */

        // HashMap solution
        public RandomListNode copyRandomList(RandomListNode head) {
            if (head == null) return null;
            Map<RandomListNode, RandomListNode> map = new HashMap<>();
            RandomListNode temp = head;
            while (temp != null) {
                map.put(temp, new RandomListNode(temp.label));
                temp = temp.next;
            }
            for (RandomListNode node : map.keySet()) {
                RandomListNode curr = map.get(node);
                curr.next = map.get(node.next);
                curr.random = map.get(node.random);
            }
            return map.get(head);
        }
    }

方法2:

update Nov 26, 2017 0:14 对于 O(1) space 的解法,有一点需要更正。以上解法中的 split 函数没有恢复原链表,实际使用中肯定是需要恢复的,所以在新的解法中更正了这一部分。