//核心工具:任意random地址到链表 index的映射的建立方法 即head到index 就相当于random到index
class Solution {
public:
RandomListNode *copyRandomList(RandomListNode *head) {
//实现根据random就能找到指向的节点的index 在cp时候用于获取当前处理节点的random指向的id的inedx
std::map<RandomListNode *, int> node_map;
//实现了通过index 就能知道节点的random指针该指向的地址
std::vector<RandomListNode *> node_vec;
RandomListNode *ptr = head;
int i = 0;
while (ptr){
//通过new的方法去新建节点 然后链接起来 来实现链表的复制的
node_vec.push_back(new RandomListNode(ptr->label));
node_map[ptr] = i;
ptr = ptr->next;
i++;
}
//避免最后节点的特殊处理
node_vec.push_back(0);
ptr = head;
i = 0;
while(ptr){
//新的链表需要重新构建 构建就是链接
node_vec[i]->next = node_vec[i+1];
if (ptr->random){
int id = node_map[ptr->random];
//一个错误的做法
//ptr->random = node_vec[id]
//根据vector[id]就能找到每个节点的random应该指向哪里
node_vec[i]->random = node_vec[id];
}
ptr = ptr->next;
i++;
}
return node_vec[0];
}
};
//来自网友的清新脱俗的解法
class Solution {
public:
Node* copyRandomList(Node* head) {
if (head == nullptr) {
return head;
}
Node *node = head;
//1. 将复制节点添加到原节点后面
while (node != nullptr) {
Node *copy = new Node(node->val, nullptr, nullptr);
copy->next = node->next;
node->next = copy;
node = copy->next;
}
//2. 复制random节点
node = head;
while (node != nullptr) {
if (node->random != nullptr) {
node->next->random = node->random->next;
}
node = node->next->next;
}
//3. 分离链表
node = head;
Node *newHead = head->next;
Node *newNode = newHead;
while (node != nullptr) {
node->next = node->next->next;
if (newNode->next != nullptr) {
newNode->next = newNode->next->next;
}
node = node->next;
newNode = newNode->next;
}
return newHead;
}
};