LeetCode 复制带随机指针的链表

给定一个链表,每个节点包含一个额外增加的随机指针,该指针可以指向链表中的任何节点或空节点。
要求返回这个链表的深拷贝。
示例:
在这里插入图片描述

输入:
{"$id":"1","next":{"$id":"2","next":null,"random":{"$ref":"2"},"val":2},"random":{"$ref":"2"},"val":1}
解释:
节点 1 的值是 1,它的下一个指针和随机指针都指向节点 2 。
节点 2 的值是 2,它的下一个指针指向 null,随机指针指向它自己。

提示:
你必须返回给定头的拷贝作为对克隆列表的引用。
思路分析:利用map关联式容器辅助。第一遍扫描复制节点,并将原链表中的所有节点与新复制的节点一一对应的关联,再扫描一遍原链表复制next、random指针内容。

/*
// Definition for a Node.
class Node {
public:
    int val;
    Node* next;
    Node* random;

    Node() {}

    Node(int _val, Node* _next, Node* _random) {
        val = _val;
        next = _next;
        random = _random;
    }
};
*/
class Solution {
public:
	Node* copyRandomList(Node* head) {
		map<Node*, Node*> myMap;
		Node *pHead = head, *tempPtr;
		//扫描链表,复制所有的节点
		while (pHead != NULL) {
			tempPtr = new Node(pHead->val, pHead->next, pHead->random);
			myMap[pHead] = tempPtr;//将原节点与新节点一一对应的关联
			pHead = pHead->next;
		}
		myMap[NULL] = NULL;
		pHead = head;
		//再次扫描链表,复制next、random指针
		while (pHead != NULL){
			myMap[pHead]->next = myMap[pHead->next];
			myMap[pHead]->random = myMap[pHead->random];
            pHead = pHead->next;
		}
		return myMap[head];
	}
};

在这里插入图片描述
方法二:

① 首先扫描链表,复制所有的节点,并将复制的节点插入到原先节点的后面。
②再次扫描节点,复制所有原节点random指针域、
③再将两个链表拆开
算法示意图
初始状态
在这里插入图片描述
执行第一步复制节点
在这里插入图片描述
执行第二步复制random指针域
在这里插入图片描述
执行第三步拆分链表。
在这里插入图片描述

/*
// Definition for a Node.
class Node {
public:
    int val;
    Node* next;
    Node* random;

    Node() {}

    Node(int _val, Node* _next, Node* _random) {
        val = _val;
        next = _next;
        random = _random;
    }
};
*/
class Solution {
public:
	Node* copyRandomList(Node* head) {
        if (head == NULL){
            return NULL;
        }
		Node *pHead = head, *tempPtr;
		//扫描链表,复制所有的节点
		while (pHead != NULL) {
			tempPtr = new Node(pHead->val, pHead->next, pHead->random);//复制节点
			//将这个复制的节点插入到复制源的后面
			tempPtr->next = pHead->next;
			pHead->next = tempPtr;
			pHead = pHead->next->next;//移动必须是移动两个一次,因为刚刚在后面插入了一个复制的节点
		}
		//再次扫描节点,复制random节点
		pHead = head;
		while (pHead != NULL) {
			if (pHead->random != NULL) {
				//pHead->next是pHead的复制,所以pHead->random->next的复制是pHead->random
				pHead->next->random = pHead->random->next;
			}
			else {
				pHead->next->random = NULL;
			}
			pHead = pHead->next->next;
		}
		//在将两个链表拆开
		pHead = head;
		Node *copyHead = pHead->next;
		while (pHead != NULL) {
			tempPtr = pHead->next;
			pHead->next = pHead->next->next;
			if (tempPtr->next != NULL) {
				tempPtr->next = tempPtr->next->next;
			}
            pHead = pHead->next;
		}
		return copyHead;
	}
};

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_41855420/article/details/87893486