【面试题】面试官:判断图是否有环?_数据结构复试问题 有向图是否有环

news2024/11/18 16:27:20
    type: 'NODE';
    name: string;
    [x: string]: any;
};
[x: string]: any;

};
export type Data = Node | Edge;
复制代码


* 测试数据如下



const data: Data[] = [
{
id: ‘1’,
data: {
type: ‘NODE’,
name: ‘节点1’
}
},
{
id: ‘2’,
data: {
type: ‘NODE’,
name: ‘节点2’
}
},
{
id: ‘3’,
data: {
type: ‘NODE’,
name: ‘节点3’
}
},
{
id: ‘4’,
source: {
cell: ‘1’
},
target: {
cell: ‘2’
},
data: {
type: ‘EDGE’
}
},
{
id: ‘5’,
source: {
cell: ‘1’
},
target: {
cell: ‘3’
},
data: {
type: ‘EDGE’
}
}
];
复制代码


* 根据数据结构和测试数据`data:Data[]`,分为以下几个步骤:
	1. 获得边的集合和节点的集合。
	2. 根据边的集合和节点的集合,获得每个节点的有向邻居节点的集合。即以每个节点的为起点,通过边连接的下一个节点的集合。例如测试数据`节点1`,通过边`id4`和边`id5`,可以连接`节点2`和`节点3`,所以`节点1`的邻居节点是`节点2`和`节点3`,而`节点2`和`节点3`无有向邻居节点。
	3. 最后根据有向邻居节点的集合,判断是否有环。


### 具体实现


* 获得边的集合和节点的集合



const edges: Map<string, Edge> = new Map(), nodes: Map<string, Node> = new Map();
const idMapTargetNodes: Map<string, Node[]> = new Map();
const initGraph = () => {
for (const item of data) {
const { id } = item;
if (item.data.type === ‘EDGE’) {
edges.set(id, item as Edge);
} else {
nodes.set(id, item as Node);
}
}
};
复制代码


* 获取有向邻居节点的集合,这里的集合,可以优化成`id`。我为了方便处理,存储了节点



const idMapTargetNodes: Map<string, Node[]> = new Map();
const initTargetNodes = () => {
for (const [id, edge] of edges) {
const { source, target } = edge;
const sourceId = source.cell, targetId = target.cell;
if (nodes.has(sourceId) && nodes.has(targetId)) { //防止有空的边,即边的起点和终点不在节点的集合里
const targetNodes = idMapTargetNodes.get(sourceId);
if (Array.isArray(targetNodes)) {
targetNodes.push(nodes.get(targetId) as Node);
} else {
idMapTargetNodes.set(sourceId, [nodes.get(targetId) as Node]);
}
}
}
};
复制代码


* 最后判断是否有环,有两种方式:递归和循环。都是深度优先遍历。`execute`是遍历所有节点,`hasCycle`是把图的某个节点做为起点,判断是否有环。如果以所有节点为起点,都没有环,说明这个图没有环。
	1. 递归。`hasCycle`判断当前节点是否有环;`checked`是做优化,防止某些节点多次检查,回溯阶段,把当前节点加入`checked`;`visited`记录当前执行的`hasCycle`里是否访问过,如果访问过,就是有环。需要注意的是,每次执行`hasCycle`时,`visited`用的是一个变量,所以在回溯阶段需要把当前节点从`visited`里删除。

const checked: Set = new Set();
const hasCycle = (node: Node, visited: Set) => {
if (checked.has(node.id)) return false;
if (visited.has(node)) return true;
visited.add(node);
const { id } = node;
const targetNodes = idMapTargetNodes.get(id);
if (Array.isArray(targetNodes)) {
for (const item of targetNodes) {
if (hasCycle(item, visited)) return true;
}
}
checked.add(node.id);
visited.delete(node);
return false;
};
const execute = () => {
const visited: Set = new Set();
for (const [id, node] of nodes) {
if (hasCycle(node, visited)) return true;
checked.add(id);
}
return false;
};
复制代码


	1. 循环。`checked`和递归时,作用一样,这里不做说明。`visited`是用来判断当前的节点是否遍历过,如果遍历过,就是有环。用循环实现深度优先遍历时,需要用`栈`来存储当前链路上的节点,即当前节点已经后代节点。并且从`栈`里面获取最后一个节点,作为当前遍历的节点。如果当前节点有向邻居节点不为空,就把有向邻居节点的最后一个节点拿出来压栈;如果有向邻居节点为空,就把当前的节点出栈。在压栈时,如果当前节点在`visited`里,就说明有环,如果没有就要把这个节点加入到`visited`。在出栈时,把当前节点从`visited`里删除掉,因为如果不删掉,当一个节点的多个邻居节点最终指向同一个节点时,会判断为有环。

const checked: Set = new Set();
const hasCycle = (node: Node) => {
const { id } = node;
if (checked.has(id)) return false;
const stack = [id];
const visited: Set = new Set();
visited.add(id);
while (stack.length > 0) {
const lastId = stack[stack.length - 1];
const targetNodes = idMapTargetNodes.get(lastId) || [];
if (targetNodes.length > 0) {

最后

前端CSS面试题文档,JavaScript面试题文档,Vue面试题文档,大厂面试题文档

.length > 0) {

最后

前端CSS面试题文档,JavaScript面试题文档,Vue面试题文档,大厂面试题文档

[外链图片转存中…(img-ze1QDx8k-1719237898712)]

[外链图片转存中…(img-pp9ZHRr7-1719237898713)]

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

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

相关文章

位置轴轴控功能块封装(CODESYS ST源代码)

博途PLC轴控功能块封装请参考下面文章链接&#xff1a; 1、S7-1200PLC位置控制功能块优化 S7-1200PLC脉冲轴位置控制功能块优化(完整SCL源代码)_s71200 脉冲轴-CSDN博客文章浏览阅读251次。博途PLC 位置控制功能块常用应用&#xff0c;可以参考下面文章链接&#xff1a;1、博…

电脑打印文件怎么操作?

有打印机用户的打印操作 对于已经拥有打印机的用户来说&#xff0c;打印文件通常是一个简单的步骤。首先&#xff0c;你需要将你的文件&#xff08;如Word、PDF、PPT等&#xff09;在电脑上打开。然后&#xff0c;点击菜单栏中的“打印”选项&#xff0c;或者快捷键CtrlP&…

ubuntu22.04安装onlyoffice社区版

安装unbuntu22.04 https://blog.csdn.net/qq_36437991/article/details/135915360 安装onlyoffice sudo apt-get update sudo apt-get upgradepostgresql sudo apt-get install postgresql创建用户和数据库 sudo -i -u postgres psql -c "CREATE USER onlyoffice WIT…

浏览器自带的IndexDB的简单使用示例--小型学生管理系统

浏览器自带的IndexDB的简单使用示例--小型学生管理系统 文章说明代码效果展示 文章说明 本文主要为了简单学习IndexDB数据库的使用&#xff0c;写了一个简单的增删改查功能 代码 App.vue&#xff08;界面的源码&#xff09; <template><div style"padding: 30px&…

BC64 牛牛的快递(c++)

牛牛的快递 题目描述输入描述输出描述示例代码 解题思路例如 题目描述 牛牛正在寄快递&#xff0c;他了解到快递在 1kg 以内的按起步价 20 元计算&#xff0c;超出部分按每 kg 1元计算&#xff0c;不足 1kg 部分按 1kg计算。如果加急的话要额外付五元&#xff0c;请问牛牛总共要…

GNSS接收机的工作原理

GNSS接收机的工作原理如下&#xff1a; 信号接收&#xff1a;GNSS接收机通过天线接收来自卫星导航系统的信号&#xff0c;这些信号包含卫星的位置、时间和健康状态等信息。 信号处理&#xff1a;接收的信号首先经过前置放大器放大&#xff0c;然后经过滤波器滤除噪声。接收机会…

2024年现代化教育与新媒体发展国际会议(MENMDIC 2024)

2024年现代化教育与新媒体发展国际会议 2024 International Conference on Modern Education and New Media Development 会议简介 2024年现代化教育与新媒体发展国际会议为教育领域的研究者和实践者提供了一个宝贵的学习和交流平台。通过参与本次会议&#xff0c;与会者不仅可…

信息学奥赛初赛天天练-34-CSP-J2021完善程序-按位异或、模拟算法、数组模拟环、约瑟夫问题应用

PDF文档公众号回复关键字:20240624 2021 CSP-J 完善程序3 1 完善程序 (单选题 &#xff0c;每小题3分&#xff0c;共30分) &#xff08;Josephus问题&#xff09;有n个人围成一个圈&#xff0c;依次标号0至n-1。从0号开始&#xff0c;依次 0&#xff0c;1&#xff0c;0&#…

uni-starter:云端一体应用快速开发的新选择

一、引言 随着移动互联网的快速发展&#xff0c;应用开发面临着日益增长的效率挑战。如何在保证应用功能丰富性的同时&#xff0c;快速迭代和上线&#xff0c;成为了众多开发者关注的焦点。在这样的背景下&#xff0c;uni-starter作为一款集成商用项目常见功能的云端一体应用快…

C++初学者指南-2.输入和输出---命令行参数

C初学者指南-2.输入和输出—命令行参数 文章目录 C初学者指南-2.输入和输出---命令行参数1.这是什么&为什么这样&#xff1f;2.如何在C中访问3.转换为std::string、int......4.字符串到数字的转换函数5.命令行参数解析库 1.这是什么&为什么这样&#xff1f; 程序调用后…

Halcon 根据霍夫变换在图像中寻找直线

一 霍夫变换 1 定义 霍夫变换是图像处理中从图像中识别几何形状的基本方法之一.几何形状包括圆&#xff0c;椭圆&#xff0c;直线等等. 2 直线方程 直线的方程可以用yk*xb 来表示&#xff0c;其中k和b是参数&#xff0c;分别是斜率和截距; 3 霍夫变换原理&#xff1a; 设…

本地服务怎么发布成rpc服务

目录 1.引入 2.user.proto 3.userservice.cc 1.引入 example文件夹作为我们框架项目的使用实例&#xff0c;在example文件夹下创建callee和caller两个文件夹 callee是RPC服务的提供者。在callee创建一个文件&#xff1a;userservice.cc 我们有没有这样一个框架&#xff0c;把…

VMware Workstation安装Windows Server2019系统详细操作步骤

虚拟机版本 VMware Workstation 16 Prp 16.2.5 build-20904516 实现操作 创建虚拟机 创建新的虚拟机 自定义->下一步 默认即可&#xff0c;下一步 稍后安装操作系统->下一步 按照图下所示选择好系统->下一步 设置好虚拟机名称和位置->下一步 默认即可&#xff0…

ONLYOFFICE桌面编辑器8.1版:个性化编辑和功能强化的全面升级

ONLYOFFICE是一款全面的办公套件&#xff0c;由Ascensio System SIA开发。该软件提供了一系列与微软Office系列产品相似的办公工具&#xff0c;包括处理文档&#xff08;ONLYOFFICE Document Editor&#xff09;、电子表格&#xff08;ONLYOFFICE Spreadsheet Editor&#xff0…

React+TS 从零开始教程(3):useState

源码链接&#xff1a;下载 在开始今天的内容之前呢&#xff0c;我们需要先看一个上一节遗留的问题&#xff0c;就是给属性设置默认值。 我们不难发现&#xff0c;这个defaultProps已经被废弃了&#xff0c;说明官方并不推荐这样做。其实&#xff0c;这个写法是之前类组件的时候…

Excel 宏录制与VBA编程 —— 12、文本字符串类型相关(附示例)

字符串分割&#xff0c;文末示例&#xff08;文末代码3附有源码&#xff09; 代码1 - 基础字符串 代码2 - 字符串拆分 代码3 - 字符串分割 Option ExplicitSub WorkbooksClear()Dim DataRange As RangeSet DataRange Range("C2:E12")DataRange.Clear End SubSub Wo…

QGIS在VS2019开发

QGIS二次开发&#xff08;1&#xff09;—加载矢量、栅格图层&#xff08;QGIS 2.14.16 && Qt-4.8.6 && VS2010 &#xff09;_qgis开发教程-CSDN博客 VS2019QT5.15.2QGIS二次开发环境搭建&#xff08;非源码方式&#xff09;_qt qgis-CSDN博客 也许面向对象课…

MVVM——CommunityToolKit第三方详情

CommunityToolkit是微软推出的轻量级工具包&#xff0c;它集成了现代、快速和模块化的 MVVM 库。 安装 在NuGet 工具箱上搜索CommunityToolKit进行下载 观测对象 ObservableObject ObservableObject 是通过实现 INotifyPropertyChanged 和 INotifyPropertyChanging 接口可观…

单门户上集成多种数据库查询入口

&#xff08;作者&#xff1a;陈玓玏&#xff09; 开源项目&#xff0c;欢迎star哦&#xff0c;https://github.com/tencentmusic/cube-studio 在一家公司&#xff0c;我们通常会有多种数据库&#xff0c;每种数据库因为其特性承担不同的角色&#xff0c;比如mysql这种轻量…

红队内网攻防渗透:内网渗透之内网对抗:横向移动篇域控系统提权NetLogonADCSPACKDC永恒之蓝CVE漏洞

红队内网攻防渗透 1. 内网横向移动1.1 横向移动-域控提权-CVE-2020-1472 NetLogon1.2 横向移动-域控提权-CVE-2021-422871.3 横向移动-域控提权-CVE-2022-269231.4 横向移动-系统漏洞-CVE-2017-01461.5 横向移动-域控提权-CVE-2014-63241. 内网横向移动 1、横向移动-域控提权-…