力扣HOT100之链表:138. 随机链表的复制

这道题要求将整个链表进行深拷贝,新链表中不包含任何原链表的节点,但是新链表中各个节点存储的值和各个节点的指向关系需要和原链表一模一样。我的思考过程如下:

1.新链表中的每一个节点的创建必须用new关键字来创建,而不能只是简单的拷贝赋值;

2.由于ramdom指针的随机性,A -> random可能指向nullptr,也可能指向A之后的某个节点,也有可能指向A之前的某个节点,也有可能指向自己,在构造链表的过程中,完全有可能出现A -> random对应的节点还没构造出来的情况,此外,按照random指针遍历链表可能出现有环的情况,从而导致无限循环。

3.要想遍历链表的所有节点,只能通过next指针进行遍历,因此在构造链表的过程中,我们应当使用next指针遍历整个链表,先将新链表的所有节点构造出来,然后再来逐个处理每一个节点的random指针的指向问题。
还有一个问题,就是原链表中的节点Arandom指针指向节点B,我们怎么将新链表中A'random指针指向B'?

我们可以使用一个整形变量offset来记录原链表中A -> random指针指向节点(B节点)相较于头节点的偏移量,然后我们在新链表中通过这个偏移量找到对应的节点,再将当前遍历到的节点的random指针指向偏移量为offset的节点。

下面结合一个简单的例子来说明一下解决的过程

代码如下

cpp 复制代码
/*
// Definition for a Node.
class Node {
public:
    int val;
    Node* next;
    Node* random;
    
    Node(int _val) {
        val = _val;
        next = NULL;
        random = NULL;
    }
};
*/

class Solution {
public:
    Node* copyRandomList(Node* head) {
        Node* new_head = head ? new Node(head -> val) : nullptr;   //新链表的头节点
        Node* current1 = head;
        Node* current2 = new_head;
        //先根据next指针将所有节点构造出来,并顺序连接
        while(current1){
            current2 -> val = current1 -> val;
            current2 -> next = current1 -> next ? new Node(current1 -> next -> val) : nullptr;
            current1 = current1 -> next;
            current2 = current2 -> next;
        }
        //按照顺序逐一构造random的指向
        current1 = head;
        current2 = new_head;
        while(current1){
            if(current1 -> random){   //random指向链表中的节点
                Node* temp_current1 = head;  //
                int offset = 0;   //计算偏移量
                while(temp_current1 != current1 -> random){
                    ++offset;
                    temp_current1 = temp_current1 -> next;
                }
                Node* temp_current2 = new_head;
                while(offset > 0){  //寻找新链表中当前节点的random指向的位置
                    temp_current2 = temp_current2 -> next;
                    --offset;
                }
                current2 -> random = temp_current2;    
            }
            current1 = current1 -> next;
            current2 = current2 -> next;
        }
        return new_head;
    }
};
相关推荐
消失的旧时光-194315 分钟前
统一并发模型:线程、Reactor、协程本质是一件事(从线程到协程 · 第6篇·终章)
java·python·算法
智者知已应修善业26 分钟前
【51单片机不用数组动态数码管显示字符和LED流水灯】2023-10-3
c++·经验分享·笔记·算法·51单片机
AI进化营-智能译站1 小时前
ROS2 C++开发系列16-智能指针管理传感器句柄|告别ROS2节点内存泄漏与野指针
java·c++·算法·ai
CS创新实验室2 小时前
从盘边到芯端——硬盘接口七十年变迁史
算法·磁盘调度
xvhao20132 小时前
单源、多源最短路
数据结构·c++·算法·深度优先·动态规划·图论·图搜索算法
MATLAB代码顾问2 小时前
多种群协同进化算法(MPCE)求解大规模作业车间调度问题——附MATLAB代码
开发语言·算法·matlab
FQNmxDG4S2 小时前
JVM内存模型详解:堆、栈、方法区与垃圾回收
java·jvm·算法
We་ct3 小时前
LeetCode 72. 编辑距离:动态规划经典题解
前端·算法·leetcode·typescript·动态规划
AI科技星3 小时前
精细结构常数α作为SI 7大基本量纲统一耦合常数的量子几何涌现理论
算法·机器学习·数学建模·数据挖掘·量子计算
txzrxz4 小时前
动态规划——背包问题
算法·动态规划