9.15 BFS中等 133 Clone Graph review 138 随机链表的复制

news2024/9/25 19:25:32

133 Clone Graph

在这里插入图片描述

在这里插入图片描述

//错误代码

class Solution {
public:
    Node* cloneGraph(Node* node) {
        //邻接表、BFS---》类似于二叉树的层次遍历
        if(!node || !node->val) return node;
        //构造队列
        queue<Node*> prev;
        prev.push(node);
        //构造新的图结点列表
        vector<Node*> adjList;
        //辅助数组
        // 哈希集合用于记录访问过的节点
        unordered_set<Node*> visited;
        visited.insert(node);
        while(prev.empty()){
            //获取结点并出栈
            Node* newNode = new Node();
            Node* curr = prev.front();prev.pop();

            newNode->val = curr->val;
            for(Node* neighbor : curr->neighbors){
                //复制对应的邻接点
                newNode->neighbors.push_back(neighbor);
                // 如果邻居没有被访问过
                if (visited.find(neighbor) == visited.end()) {
                    prev.push(neighbor);         // 将未访问的邻居加入队列
                    visited.insert(neighbor); // 标记为已访问
                }
            }
            adjList.push_back(newNode);
        }
        return adjList[0];
    }
};)
  • 在克隆图的过程中,直接使用了原图中的邻居列表(newNode->neighbors.push_back(neighbor)),而没有克隆邻居节点的副本。实际上,需要复制整个图中的节点及其连接关系,因此应为每个节点创建新的副本,而不是直接使用原图的邻居节点
  • 图的克隆和链表的复制(特别是带随机指针的链表的深度复制138) 很类似。两者都涉及节点的复制,并且不仅仅是单独复制节点本身,还必须考虑其邻接点或其他关联节点(例如,图的邻居节点或链表的随机指针)。
/*
// Definition for a Node.
class Node {
public:
    int val;
    vector<Node*> neighbors;
    Node() {
        val = 0;
        neighbors = vector<Node*>();
    }
    Node(int _val) {
        val = _val;
        neighbors = vector<Node*>();
    }
    Node(int _val, vector<Node*> _neighbors) {
        val = _val;
        neighbors = _neighbors;
    }
};
*/

class Solution {
public:
    Node* cloneGraph(Node* node) {
        if(!node) return nullptr;
        //原结点-->克隆结点
        unordered_map<Node* , Node*> cloneNodes;
        //BFS
        queue<Node*> prev;
        prev.push(node);
        //第一个克隆结点
        cloneNodes[node] = new Node(node->val);

        while(!prev.empty()){
            Node* curr = prev.front();
            prev.pop();

            for(Node* neighbor : curr->neighbors){
                //如果邻居结点还没有被克隆
                if(cloneNodes.find(neighbor) == cloneNodes.end()){
                    cloneNodes[neighbor] = new Node(neighbor->val);
                    //加入队列
                    prev.push(neighbor);
                }
                //将克隆的邻居节点加入当前克隆节点的邻接表
                cloneNodes[curr]->neighbors.push_back(cloneNodes[neighbor]);
            }
        }
        return cloneNodes[node];

    }
};

138 随机链表的复制

在这里插入图片描述

/*
// 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) {
        if(!head) return nullptr;
        //建立新链表
        Node* p = head;             //p是原链表指针
        Node* dum = new Node(0);
        Node* temp = dum;           //temp是新链表指针

        //构造哈希表
        unordered_map<Node* , Node*> copyList;
        //第一次遍历原链表,复制next指针
        while(p){
            Node* node = new Node(p->val);
            temp->next = node;

            copyList[p] = node;

            temp = temp->next;
            p = p->next;
        }
        //第二次遍历原链表,复制random
        p = head;
        temp = dum->next;
        while(p){
            if(p->random != nullptr){
                temp->random = copyList[p->random];
            }
            temp = temp->next;
            p = p->next;
        }
        return dum->next;


    }
};

summary 哈希表与克隆:用于存储原节点和新节点的映射

1. 防止重复克隆

当我们遍历图或链表时,如果不使用哈希表,就可能会多次创建同一个节点的副本,从而浪费内存和时间。哈希表通过记录原节点和对应的新节点,确保每个节点只会被克隆一次。每当需要访问一个节点的邻居(在图中)或者 nextrandom(在链表中)时,哈希表可以直接提供已克隆的节点,而无需重复创建。

2. 保证边的复制

当你遍历一个节点时,你不仅需要复制该节点,还需要复制它所有的边(即图中的邻接点或者链表中的指针)。这里哈希表起到了关键作用:

  • 对于图的克隆,当你克隆一个节点时,它的邻居节点可能已经被克隆,也可能还没有。如果没有克隆,哈希表会创建并存储这个邻居节点的克隆版;如果已经克隆,你可以通过哈希表找到对应的克隆节点,并将它加入当前节点的邻接表中,确保边的复制。

在这里插入图片描述
在这里插入图片描述

  • 对于链表,类似地,你需要通过哈希表将 randomnext 指针正确指向克隆后的节点,而不是指向原链表中的节点。

在这里插入图片描述
在这里插入图片描述

3. 流程示例

以图为例,当我们遍历到一个节点 ( A ) 时,如果节点 ( A ) 的邻居 ( B ) 还未被克隆,哈希表就会克隆 ( B ) 并将其存储。接下来,无论你何时再次遇到 ( B ),都可以直接从哈希表中获取克隆节点。这样,边 ( A - B ) 也就得以正确复制。

直观的解释:

通过哈希表的存储和查找机制,可以保证每次访问节点时,邻居的指向都是已经克隆的副本,而不是原图中的节点,从而保证边(指针)的完整性

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2138015.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ESP8266_MicroPython——ADC_PWM

MicroPython 文章目录 MicroPython前言一、ADC二、PWM 前言 这一节简单学习一下ACD和PWM 一、ADC ADC(analog to digital conversion) 模拟数字转换。意思就是将模拟信号转化成数字信号&#xff0c;由于单片机只能识别二级进制数字&#xff0c;所以外界模拟信号常常会通过 A…

OpenCV结构分析与形状描述符(22)计算图像中某个轮廓或区域的矩函数moments()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 计算一个多边形或光栅化形状直到三阶的所有矩。 该函数计算一个向量形状或光栅化形状直到三阶的矩。结果返回在 cv::Moments 结构中。 函数原型…

数据结构————二叉树基础知识(零基础包会的!)

今天带来数据结构二叉树的知识&#xff0c;保证大家不会离散数学或者没有数据结构基础&#xff0c;也能明明白白的。 一&#xff0c;树 1&#xff0c;树的结构 我们在了解什么是二叉树之前我们先了解下什么是树&#xff0c;树是一种非线性的数据结构&#xff0c;它是由n个节点…

Bootstrap 警告信息(Alerts)使用介绍

本章将讲解警告&#xff08;Alerts&#xff09;以及 Bootstrap 所提供的用于警告的 class。警告&#xff08;Alerts&#xff09;向用户提供了一种定义消息样式的方式。它们为典型的用户操作提供了上下文信息反馈。 您可以为警告框添加一个可选的关闭按钮。为了创建一个内联的可…

C# 实现二维数据数组导出到 Excel

目录 功能需求 范例运行环境 Excel DCOM 配置 设计实现 组件库引入 ​编辑​ 方法设计 生成二维数据数组 核心方法实现 调用示例 总结 功能需求 将数据库查询出来的数据导出并生成 Excel 文件&#xff0c;是项目中经常使用的一项功能。本文将介绍通过数据集生成二维…

基于TCP的网络计算器实现

目录 一. 重新理解协议 二. 序列化与反序列化 2.1 概念 2.2 重新理解 read、write、recv、send 和 tcp 为什么支持全双工 2.3 理解TCP面向字节流 三. 请求应答模块实现 3.1 添加与解析报头 3.2 定制协议&#xff1a; 3.3 Json 四. 计算模块实现…

字典转换(根据字典转换、根据id转换)

一、三种转换方式 翻译场景:序列化时候转换 适用类型: 字典type转中文用户id转用户名部门id转名称附件id转url路径1.1 根据另一个映射字段 翻译保存到此字段 根据创建者createBy的id,查询名称设置到 createName 1.2 直接根据此字段值翻译后替换此字段值 ossId 替换为 url …

医疗监测数据检测系统源码分享

医疗监测数据检测检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Computer…

vue3透传、注入

属性透传 传递给子组件时&#xff0c;没有被子组件消费的属性或事件&#xff0c;常见的如id、class 注意1 1.class、style是合并的&#xff0c;style中如果出现重复的样式&#xff0c;以透传属性为准2.id属性是以透传属性为准&#xff0c;其他情况透传属性名相同&#xff0c…

深度学习云服务器免费使用教程

#云服务器# #深度学习# #人工智能# #计算机视觉# 本文为各位学习深度学习的入门选手而创建&#xff0c;降低深度学习的入门门槛。 谷歌云服务器Colab&#xff1a; T4GPU。限额&#xff0c;需要科学上网&#xff0c;不能使用终端。 谷歌云服务器地址&#xff1a;欢迎使用 C…

C语言 | Leetcode C语言题解之第405题数字转换为十六进制数

题目&#xff1a; 题解&#xff1a; char * toHex(int num){int i0;char *nums(char*)malloc(sizeof(char)*32);unsigned int newnum(unsigned int)num;if(num0){nums[0]0;nums[1]\0;return nums;}while(newnum>1){int flagnewnum%16;newnum/16;if(flag<9){nums[i]flag0…

华为OD机试 - 计算误码率(Python/JS/C/C++ 2024 E卷 100分)

华为OD机试 2024E卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试真题&#xff08;Python/JS/C/C&#xff09;》。 刷的越多&#xff0c;抽中的概率越大&#xff0c;私信哪吒&#xff0c;备注华为OD&#xff0c;加入华为OD刷题交流群&#xff0c;…

Acwing 队列

模拟队列 主要思想&#xff1a;先进先出&#xff08;注意与栈做区分&#xff09;&#xff0c;队尾插入&#xff0c;队头删除。设置一个数组存储数据&#xff0c;队头指针指向队列第一个元素&#xff08;初始为0&#xff09;&#xff0c;队尾指针指向最后一个元素&#xff08;初…

Qt常用控件——QSpinBox

文章目录 QSpinBox核心属性及信号点餐示例 QSpinBox核心属性及信号 QSpinBox或者QDoubleSpinBox表示微调框&#xff0c;带有按钮的输入框&#xff0c;可以用来输入整数/浮点数或者通过点击按钮调整数值大小 QSpinBox和QDoubleSpinBox用法基本相同&#xff0c;本篇以QSpinBox为…

Ubuntu 安装包下载(以20版本 阿里镜像站为例子)

Ubuntu安装包下载 上一篇文章写了一些国内常用的镜像站&#xff0c;这篇以阿里云镜像站Ubuntu20版本为例。 https://mirrors.aliyun.com/ubuntu-releases/ 1.点击自己想要下载的版本 2.点击以amd64.iso为结尾的文件&#xff0c;这个是安装文件&#xff0c;如果是桌面端&…

C++初阶学习——探索STL奥秘——vector的模拟实现

vector的结构比较特殊&#xff0c;成员变量为三个指针 #pragma once #include <iostream> using std::cin; using std::cout; using std::endl;#include <string> using std::string;namespace Yohifo {template<class T>class vector{public:typedef T val…

使用jmeter做性能测试实践过程中需要注意什么

前言 在驾驭Apache JMeter进行性能测试之旅中&#xff0c;深刻理解其特性和限制是至关重要的。以下是提升JMeter效能的关键策略&#xff0c;旨在挖掘其潜力&#xff0c;克服局限&#xff0c;实现精准测试。 1.精确调控线程数 推荐阈值&#xff1a;将线程数控制在300以内&…

模拟视频推到WVP推流列表

效果 1. wvp创建RTMP 2. 使用ffmpeg将本地的视频转为rtmp ffmpeg -re -i F:rtsp\123.mp4 -c copy -f flv rtmp://192.168.1.237:1935/cd/10001?sign=Z4Y3eYeSg

HTML5之canvas绘图

介绍 <canvas> 是 HTML5 引入的一个强大元素&#xff0c;允许直接在网页上进行矢量图形和位图图像的绘制&#xff0c;为网页提供了一个动态图形渲染的平台。这一特性极大丰富了网页的表现力&#xff0c;特别是在数据可视化、游戏开发、交互式图表和动画制作等领域发挥着…

第311题| 超好用!二重积分求旋转体体积公式|武忠祥老师每日一题

第一步&#xff1a; &#xff08;1&#xff09;找渐近线&#xff0c;先看水平渐近线&#xff0c;看x趋于无穷时&#xff0c;y有没有趋于一个有限的值。 , 得出水平渐近线y1。因为左右两边都是水平渐近线&#xff0c;所以没有斜渐近线。 第二步&#xff1a; 画出图像&#…