图中的最长环

说在前面

🎈不知道大家对于算法的学习是一个怎样的心态呢?为了面试还是因为兴趣?不管是处于什么原因,算法学习需要持续保持,今天让我们一起来看看这一道题目————图中的最长环,图论题目中比较常见的环路问题。

题目描述

给你一个 n 个节点的 有向图 ,节点编号为 0 到 n - 1 ,其中每个节点 至多 有一条出边。

图用一个大小为 n 下标从 0 开始的数组 edges 表示,节点 i 到节点 edges[i] 之间有一条有向边。如果节点 i 没有出边,那么 edges[i] == -1 。

请你返回图中的 最长 环,如果没有任何环,请返回 -1 。

一个环指的是起点和终点是 同一个 节点的路径。

示例 1:

image.png

输入:edges = [3,3,4,2,3]
输出去:3
解释:图中的最长环是:2 -> 4 -> 3 -> 2 。
这个环的长度为 3 ,所以返回 3 。

示例 2:

image.png

输入:edges = [2,-1,3,1]
输出:-1
解释:图中没有任何环。

提示:

n == edges.length
2 <= n <= 10^5
-1 <= edges[i] < n
edges[i] != i

思路分析

题目的要求很清晰,就是要我们找出单向连通图中的最长环,那么在一个图中我们要怎样来判断有没有存在环呢?因为这道题目中的图是单向图,所以我们可以很简单找出图中的环,如下图:

image.png
我们从节点1出发,遍历过的节点都做上标记,然后不断的往图的下一个节点遍历,直到遇到已经做过标记的节点,则说明其前面也遍历过,也即是已经形成了环。这样说的话我们是不是可以把所有节点都当成起点走一遍,找出所有环中的最长环就可以?让我们动手写代码试一下,按照这个思路我们可以写出这样一段代码:

/*** @param {number[]} edges* @return {number}*/var longestCycle = function(edges) {let res = -1;const dfs = (node,steps,step = 0)=>{if(edges[node] == -1) return -1;if(steps[node] <= step){res = Math.max(step - steps[node],res);return step;}steps[node] = step;dfs(edges[node],steps,step + 1);}for(let i = 0; i < edges.length; i++){dfs(i,new Array(edges.length).fill(Infinity));}return res > 0 ? res : -1;
};

image.png
测试一下,好像没问题,然后自信提交代码

image.png

回头看一下数据规模2 <= n <= 10^5,这样做确实太暴力了,那就来看看可以怎么优化:

image.png
上图中橙色路径为从节点1出发的遍历路线,蓝色路径为从节点2出发的遍历路线,从图中我们可以很明显的看成蓝色路线是橙色路线中的一部分,因为节点2在节点1的遍历路径中,所以节点2往后的遍历路线一定是包含在节点1的遍历路线中,所以我们可以记录一下每个节点的遍历情况,如果是已经遍历过的节点的话,我们不应该重复遍历,所以代码可以这样进行优化:

  • 使用一个数组来记录遍历过程中每一个节点的遍历情况(visited)
  • 使用一个map来存放在当前路径中已经遍历过的节点所需步数(steps)
  • 遇到map中存在的节点时更新最长环长度

AC代码

/*** @param {number[]} edges* @return {number}*/var longestCycle = function(edges) {let res = -1;const dfs = (node,steps = {},step = 0)=>{if(visited[node] || steps[node] <= step || edges[node] == -1){if(steps[node] < step) res = Math.max(step - steps[node],res);return;}steps[node] = step; visited[node] = true;dfs(edges[node],steps,step + 1);}const visited = new Array(edges.length).fill(false);for(let i = 0; i < edges.length; i++) dfs(i);return res;
};

image.png

公众号

关注公众号『前端也能这么有趣』,获取更多有趣内容。

说在后面

🎉 这里是 JYeontu,现在是一名前端工程师,有空会刷刷算法题,平时喜欢打羽毛球 🏸 ,平时也喜欢写些东西,既为自己记录 📋,也希望可以对大家有那么一丢丢的帮助,写的不好望多多谅解 🙇,写错的地方望指出,定会认真改进 😊,偶尔也会在自己的公众号『前端也能这么有趣』发一些比较有趣的文章,有兴趣的也可以关注下。在此谢谢大家的支持,我们下文再见 🙌。

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

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

相关文章

C语言笔试例题_指针专练30题(附答案解析)

C语言笔试例题_指针专练30题(附答案解析) 指针一直是C语言的灵魂所在&#xff0c;是掌握C语言的必经之路&#xff0c;收集30道C语言指针题目分享给大家&#xff0c;测试环境位64位ubuntu18.04环境&#xff0c;如有错误&#xff0c;恳请指出&#xff0c;文明讨论&#xff01;&am…

基于SSM+JSP网上订餐管理系统(Java毕业设计)

大家好&#xff0c;我是DeBug&#xff0c;很高兴你能来阅读&#xff01;作为一名热爱编程的程序员&#xff0c;我希望通过这些教学笔记与大家分享我的编程经验和知识。在这里&#xff0c;我将会结合实际项目经验&#xff0c;分享编程技巧、最佳实践以及解决问题的方法。无论你是…

蓝桥杯2021年5月青少组Python程序设计国赛真题

30 个人在一条船上,超载&#xff0c;需要 15 人下船于是人们排成一队&#xff0c;排队的位置即为他们的编号。报数,从1开始,数到9的人下船。如此循环,直到船上仅剩15 人为止&#xff0c;问都有哪些编号的人下船了呢? 2】判断101-200之间有多少个素数&#xff0c;并输出所有素数…

Leetcode每日一题

https://leetcode.cn/problems/binary-tree-preorder-traversal/ 这道题目需要我们自行进行创建一个数组&#xff0c;题目也给出我们需要自己malloc一个数组来存放&#xff0c;这样能达到我们遍历的效果&#xff0c;我们来看看他的接口函数给的是什么。 可以看到的是这个接口函…

5_CSS三大特性盒子模型

第5章-盒子模型【比屋教育】 本课目标&#xff08;Objective&#xff09; 掌握CSS三大特性理解什么是盒子模型掌握内边距padding的用法掌握外边距margin的用法 1. CSS的层叠&#xff0c;继承&#xff0c;优先级 1.1 CSS层叠 层叠&#xff1a;是指多个CSS样式叠加到同一个元…

Web(8)SQL注入

Web网站&#xff08;对外门户&#xff09; 原理&#xff1a;not>and>or(优先级) 一.低级注入 order by的作用是对字段进行排序&#xff0c;如order by 5&#xff0c;根据第五个字段 进行排序&#xff0c;如果一共有4个字段&#xff0c;输入order by 5系统就会报错不 …

详细介绍开源固件-TF-A

什么是TF-A&#xff1f; TF-A&#xff08;Trusted Firmware-A&#xff09;是一种用于嵌入式系统的开源固件&#xff0c;而不是Linux的一部分。TF-A主要用于ARM架构的处理器和设备&#xff0c;它提供了一组安全和可信任的软件组件&#xff0c;用于引导和初始化系统。 如下是其…

GD32F30X-RT-Thread学习-线程管理

1. 软硬件平台 GD32F307E-START Board开发板MDK-ARM Keil 2.RT-Thread Nano 3.RT-Thread 内核学习-线程管理 ​ 在多线程操作系统中&#xff0c;可以把一个复杂的应用分解成多个小的、可调度的、序列化的程序单元&#xff0c;当合理地划分任务并正确地执行时&#xff0c;这…

qt可以详细写的项目或技术

1.QT 图形视图框架 2.QT 模型视图结构 3.QT列表显示大量信息 4.QT播放器 5.QT 编解码 6.QT opencv

Bypass open_basedir

讲解 open_basedir是php.ini中的一个配置选项&#xff0c;可用于将用户访问文件的活动范围限制在指定的区域。 假设open_basedir/var/www/html/web1/:/tmp/&#xff0c;那么通过web1访问服务器的用户就无法获取服务器上除了/var/www/html/web1/和/tmp/这两个目录以外的文件。…

洛谷 P8674 [蓝桥杯 2018 国 B] 调手表

文章目录 [蓝桥杯 2018 国 B] 调手表题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1 提示 题意解析CODE分析一下复杂度 [蓝桥杯 2018 国 B] 调手表 题目描述 小明买了块高端大气上档次的电子手表&#xff0c;他正准备调时间呢。 在 M78 星云&#xff0c;时间的计量…

JVM虚拟机:命令行查看JVM垃圾回收器的执行信息

在eclipse中打开命令行窗口 window->show view->Terminal 这样就打开了Terminal窗口&#xff0c;效果如下所示&#xff1a; java -XX:PrintCommandLineFlags -version 这个命令可以查看一些配置信息&#xff0c;其中最重要的配置信息就是&#xff0c;当前使用的G1回收器…

键盘打字盲打练习系列之成为大师——5

一.欢迎来到我的酒馆 盲打&#xff0c;成为大师&#xff01; 目录 一.欢迎来到我的酒馆二.关于盲打你需要知道三.值得收藏的练习打字网站 二.关于盲打你需要知道 盲打系列教程&#xff0c;终于写到终章了。。。一开始在看网上视频&#xff0c;看到up主熟练的打字技巧&#xff…

LabVIEW与Tektronix示波器实现电源测试自动化

LabVIEW与Tektronix示波器实现电源测试自动化 在现代电子测试与测量领域&#xff0c;自动化测试系统的构建是提高效率和精确度的关键。本案例介绍了如何利用LabVIEW软件结合Tektronix MDO MSO DPO2000/3000/4000系列示波器&#xff0c;开发一个自动化测试项目。该项目旨在自动…

MYSQL练题笔记-高级查询和连接-指定日期的产品价格

这依旧是中等题&#xff0c;想了好久&#xff0c;终于理解了很开心&#xff01; 一、题目相关内容 1&#xff09;相关的表和题目 2&#xff09;帮助理解题目的示例&#xff0c;提供返回结果的格式 二、自己初步的理解 题目是找出2019-08-16 时全部产品的价格&#xff0c;所以…

使用最小花费爬楼梯

1.状态表示 2.状态转移方程 3.初始化 保证填表时&#xff0c; 不越界 4.填表顺序 从左往右 5.返回值 解法2&#xff1a; 1.状态表示 2.状态转移方程 3.初始化 4.填表 从右往左 5.返回值 min( dp[0] , dp[1] ) ----------------------------------------------------…

java+springboot+ssm学生社团管理系统76c2e

本系统包括前台和后台两个部分。前台主要是展示社团列表、社团风采、社团活动、新闻列表等&#xff0c;前台登录后进入个人中心&#xff0c;在个人中心能申请加入社团、查看参加的社团活动等&#xff1b;后台为管理员与社团负责人使用&#xff0c;应用于对社团的管理及内容发布…

常见统计学习方法特点总结

1. 概述 方法适用问题模型特点模型类型学习策略损失函数学习算法1感知机二分类分离超平面判别模型极小化误分点到超平面距离误分点到超平面距离SGD2KNN多分类&#xff0c;回归特征空间&#xff0c;样本点判别模型---3朴素贝叶斯多分类特征与类别的联合概率分布&#xff0c;条件…

【CMU 15-445】Proj2 Hash Index

EXTENDIBLE HASH INDEX 通关记录Task1 Read/Write Page Guards移动构造函数Drop方法移动赋值运算符析构函数UpgradeRead函数FetchPageBasic、FetchPageRead、FetchPageWrite、NewPageGuarded Task2 Extendible Hash Table PagesHeaderPageDirectoryPageBucketPage Task3 Extend…

Python字典去重竟然比集合去重快速40多倍

这里写目录标题 对比代码结果图代码解析 对比代码 from glob import glob from tqdm import tqdm import time path_listglob("E:/sky_150b/任务组_20231207_2023/*.jsonl") # for two in tqdm(path_list): onepath_list[0]with open(one,"r",encoding&q…