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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章