複製包含任意指針的鏈表 Copy List with Random Pointer

問題:node

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.dom

Return a deep copy of the list.this

解決:spa

【題意】深拷貝一個鏈表,鏈表除了含有next指針外,還包含一個random指針,該指針指向字符串中的某個節點或者爲空。指針

① 難點就在於如何處理隨機指針的問題,用Hash map來縮短查找時間,HashMap的key存原始pointer,value存新的pointer。第一遍遍歷生成全部新節點時同時創建一個原節點和新節點的哈希表,第二遍給隨機指針賦值時,查找時間是常數級。時間複雜度O(n),空間複雜度O(n)。字符串

假設原始鏈表以下,細線表示next指針,粗線表示random指針,沒有畫出的指針均指向NULL:get

/**
 * 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 {//4ms
    public RandomListNode copyRandomList(RandomListNode head) {
        if (head == null) {
            return null;
        }
        Map<RandomListNode,RandomListNode> map = new HashMap<>();
        RandomListNode res = new RandomListNode(head.label);//複製節點
        RandomListNode node = res;
        RandomListNode cur = head.next;
        map.put(head,res);//key爲舊節點,value爲新節點
        while(cur != null){ //依次建立新的節點並將它們鏈接起來
            RandomListNode tmp = new RandomListNode(cur.label);
            node.next = tmp;
            map.put(cur,tmp);
            node = node.next;
            cur = cur.next;
        }
        node = res;
        cur = head;
        while(node != null){
            node.random = map.get(cur.random);//由於第一遍已經把鏈表複製好了而且也存在HashMap裏了,因此只需從HashMap中,把當前舊的cur.random做爲key值,獲得新的value的值,並把其賦給新node.random就好。
            node = node.next;
            cur = cur.next;
        }
        return res;
    }
}it

② 使用另外一種方法,能夠分爲如下三個步驟:io

1. 在原鏈表的每一個節點後面拷貝出一個新的節點class

2. 依次給新的節點的隨機指針賦值,並且這個賦值很是容易 cur->next->random = cur->random->next

3. 斷開鏈表可獲得深度拷貝後的新鏈表

public class Solution {//2ms     public RandomListNode copyRandomList(RandomListNode head) {         if (head == null) {             return null;         }         RandomListNode cur = head;         while(cur != null){             RandomListNode node = new RandomListNode(cur.label);//複製節點             node.next = cur.next;             cur.next = node;             cur = node.next;         }         cur = head;         while(cur != null){//爲節點賦random值             if(cur.random != null){                 cur.next.random = cur.random.next;             }             cur = cur.next.next;         }         cur = head;         RandomListNode res = head.next;         while(cur != null){//斷開鏈接,獲得複製的鏈表             RandomListNode tmp = cur.next;             cur.next = tmp.next;             if (tmp.next != null) {                 tmp.next = tmp.next.next;                 }             cur = cur.next;         }         return res;     } }

相關文章
相關標籤/搜索