lintcode105- Copy List with Random Pointer- medium

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?

1. O(n)空间:和deep copy graph类似,一开始建一个Map,映射原始点和新创点,之后遍历过去一个个把原始的边在新的链表里连上。a.造节点并在map里输入旧新结点的映射关系 b.根据旧结点信息在新结点中把链条关系连上

2.O(1)空间:巧妙三步走:a.创造新节点紧跟在屁股后。1-1'-2-2'-3-3'-4-4'-null。b.把新的random指针连好(crt.next.random = crt.random.next) c.把两个缠在一起的解旋

细节:1.小心crt.random是null的情况,小心head是null的情况,小心最后4-4'-null时crt指到null就不能延续后指crt.next的情况,总之这题里很多null指针报错的地方,你一定把所有用到xx.null的地方都检查一遍,看xx会不会是null。2.解旋前先把新链表的头地址提出来,避免解旋后你用head.next已经再也不能索引到它的情况。

法1.O(n)空间

/**
 * 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.
     */
    public RandomListNode copyRandomList(RandomListNode head) {
        // write your code here
        Map<RandomListNode, RandomListNode> map = new HashMap<>();
        
        // copy the node and make connection in map
        RandomListNode crt = head;
        map.put(null, null);
        while (crt != null) {
            RandomListNode copy = new RandomListNode(crt.label);
            map.put(crt, copy);
            crt = crt.next;
        }
        
        // use map to link the random and next in the new linkedList
        crt = head;
        while (crt != null) {
            RandomListNode crtCopy = map.get(crt);
            crtCopy.next = map.get(crt.next);
            crtCopy.random = map.get(crt.random);
            crt = crt.next;
        }
        
        return map.get(head);
    }
}

法2.O(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.
     */
    public RandomListNode copyRandomList(RandomListNode head) {
        // write your code here
        
        RandomListNode crt = head;
        while (crt != null) {
            RandomListNode temp = crt.next;
            crt.next = new RandomListNode(crt.label);
            crt.next.next = temp;
            crt = temp;
        }
        
        crt = head;
        while (crt != null) {
            // 小心crt.random是null的情况!
            crt.next.random = crt.random == null ? null : crt.random.next;
            crt = crt.next.next;
        }
        
        crt = head;
        // 小心head是null的情况,用到xx.next的地方都注意一下xx会不会是null出错
        RandomListNode copy = crt == null ? crt : crt.next;
        // 要提早把这个头存出来以便后续返回
        RandomListNode copyHead = head.next;
        while (crt != null) {
            RandomListNode temp = crt.next.next;
            crt.next = temp;
            // 拆开的时候小心null情况,因为你两条路要从一个null拆两个null出来
            // 这里不处理会报空指针,不能读取null.next
            copy.next = temp == null ? temp : temp.next;
            crt = temp;
            copy = crt == null ? crt : crt.next;
        }
        
        return copyHead;
    }
}
原文地址:https://www.cnblogs.com/jasminemzy/p/7858980.html