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.

  節點結構如下:

class Node {
public:
    int val;
    Node* next;
    Node* random;
    
    Node(int _val) {
        val = _val;
        next = NULL;
        random = NULL;
    }
};

  就是節點除了有next節點,還有一個指向隨機節點的指針,需要深複製一個出來。主要有兩種方法:
1、用一個unordered_map來存儲節點的隨機關係
2、利用鏈表特點的O(1)額外空間進行復制:因爲使用map的很容易理解,所以面試時經常會問能不能不用額外空間完成

一、unordered_map

Node* copyRandomList(Node* head) {
	if (!head) return nullptr;
	const auto head_cpy = head;
	unordered_map<Node*, Node*> mmp;
	while (head) {   // 沒有環
		mmp[head] = new Node(head->val, nullptr, nullptr);
		head = head->next;
	}
	head = head_cpy;
	while(head) {
		mmp[head]->next = mmp[head->next];
		mmp[head]->random = mmp[head->random];
		head = head->next;
	}
	return mmp[head_cpy];
}

二、利用鏈表特點
  由於鏈表每個節點原本帶有一個next指針,指向下一個節點,可以利用鏈表特點,在每一個原有節點後邊新增一個節點,用於複製前邊的節點,然後依次給新的節點的 random 指針賦值(這個賦值非常容易 cur->next->random = cur->random->next,因爲要指向新加的節點),最後跳過所有原有節點,就是新的複製出來的鏈表了。

Node* copyRandomList(Node* head) {
    if (!head) return nullptr;
    Node *cur = head;
    while (cur) {
        Node *t = new Node(cur->val);
        t->next = cur->next;
        cur->next = t;
        cur = t->next;
    }
    cur = head;
    while (cur) {
        if (cur->random) cur->next->random = cur->random->next;
        cur = cur->next->next;
    }
    cur = head;
    Node *res = head->next;
    while (cur) {
        Node *t = cur->next;
        cur->next = t->next;
        if (t->next) t->next = t->next->next;
        cur = cur->next;
    }
    return res;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章