当前位置: 首页 > news >正文

力扣 Hot 100 刷题记录 - 随机链表的复制

力扣 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 指针的指向。常用的方法是 哈希表原地复制,具体步骤如下:

  1. 哈希表法

    • 使用哈希表存储原节点和新节点的映射关系。
    • 第一次遍历链表,创建新节点并建立映射。
    • 第二次遍历链表,根据哈希表设置新节点的 nextrandom 指针。
  2. 原地复制法

    • 在原链表的每个节点后面插入一个新节点,新节点的值与原节点相同。
    • 设置新节点的 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; // 返回新链表的头节点
    }
};

相关文章:

  • 力扣hot100——多维动态规划
  • 线性代数笔记28--奇异值分解(SVD)
  • 揭开AI-OPS 的神秘面纱 第四讲 AI 模型服务层(自研方向)
  • QT快速入门-信号与槽
  • 34.二叉树进阶3(平衡二叉搜索树 - AVL树及其旋转操作图解)
  • Flask框架中局部刷新页面
  • 北斗短报文+5G:遨游通信终端开启全域智能物联新时代
  • RAG技术的PDF智能问答系统
  • Effective Python:(18)作用域问题
  • 番外篇 - Docker的使用
  • VSCode 配置优化指南
  • 【从零开始学习计算机科学】硬件设计与FPGA原理
  • r1-reasoning-rag:一种新的 RAG 思路
  • RtlLookupAtomInAtomTable函数分析之RtlpAtomMapAtomToHandleEntry函数的作用是验证其正确性
  • 【ArcGIS】地理坐标系
  • 空间域与频域图像处理
  • 基于DeepSeek的智慧医药系统(源码+部署教程)
  • C语言单链表头插法
  • 嘉立创:电子产业革新背后的隐形巨擘
  • C语言——【全局变量和局部变量】
  • 做英文网站常用的字体/外贸推广方式都有哪些
  • 网站建设和维护工作内容/磁力猫torrentkitty官网
  • 找网站公司做网站/昆明装饰企业网络推广
  • 新闻发布稿/网站seo内容优化
  • 网站建设攵金手指科杰壹陆/网络营销的特点分别是
  • wordpress无插件下载/优化大师优化项目有