成都房地产网seo快速排名的方法
力扣 Hot 100 刷题记录 - 随机链表的复制
题目描述
随机链表的复制 是力扣 Hot 100 中的一道经典题目,题目要求如下:
给你一个长度为 n
的链表,每个节点包含一个额外增加的随机指针 random
,该指针可以指向链表中的任何节点或空节点。
构造这个链表的 深拷贝。深拷贝应该正好由 n
个全新节点组成,其中每个新节点的值都设为其对应的原节点的值。新节点的 next
指针和 random
指针也都应指向复制链表中的新节点,并使原链表和复制链表中的这些指针能够表示相同的链表状态。复制链表中的指针都不应指向原链表中的节点。
示例 1:
输入:head = [[7,null],[13,0],[11,4],[10,2],[1,0]]
输出:[[7,null],[13,0],[11,4],[10,2],[1,0]]
示例 2:
输入:head = [[1,1],[2,1]]
输出:[[1,1],[2,1]]
示例 3:
输入:head = [[3,null],[3,0],[3,null]]
输出:[[3,null],[3,0],[3,null]]
解题思路
这道题的核心是复制一个带有随机指针的链表,难点在于如何处理 random
指针的指向。常用的方法是 哈希表 或 原地复制,具体步骤如下:
-
哈希表法:
- 使用哈希表存储原节点和新节点的映射关系。
- 第一次遍历链表,创建新节点并建立映射。
- 第二次遍历链表,根据哈希表设置新节点的
next
和random
指针。
-
原地复制法:
- 在原链表的每个节点后面插入一个新节点,新节点的值与原节点相同。
- 设置新节点的
random
指针。 - 分离原链表和新链表。
C++ 代码实现
方法一:哈希表法
/*
// Definition for a Node.
class Node {
public:int val;Node* next;Node* random;Node(int _val) {val = _val;next = nullptr;random = nullptr;}
};
*/
class Solution {
public:Node* copyRandomList(Node* head) {if (!head) return nullptr;// 哈希表:原节点 -> 新节点unordered_map<Node*, Node*> map;// 第一次遍历:创建新节点并建立映射Node* curr = head;while (curr) {map[curr] = new Node(curr->val);curr = curr->next;}// 第二次遍历:设置新节点的 next 和 random 指针curr = head;while (curr) {map[curr]->next = map[curr->next];map[curr]->random = map[curr->random];curr = curr->next;}return map[head]; // 返回新链表的头节点}
};
### 方法一:原地复制法
class Solution {
public:Node* copyRandomList(Node* head) {if (!head) return nullptr;// 第一步:在每个原节点后面插入一个新节点Node* curr = head;while (curr) {Node* newNode = new Node(curr->val);newNode->next = curr->next;curr->next = newNode;curr = newNode->next;}// 第二步:设置新节点的 random 指针curr = head;while (curr) {if (curr->random) {curr->next->random = curr->random->next;}curr = curr->next->next;}// 第三步:分离原链表和新链表Node* newHead = head->next;curr = head;while (curr) {Node* newNode = curr->next;curr->next = newNode->next;if (newNode->next) {newNode->next = newNode->next->next;}curr = curr->next;}return newHead; // 返回新链表的头节点}
};