1. 程式人生 > >lintcode105- Copy List with Random Pointer- medium

lintcode105- Copy List with Random Pointer- medium

head 所有 讀取 new style nal problem any strong

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;
    }
}

lintcode105- Copy List with Random Pointer- medium