题目

2360. 图中的最长环

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

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

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

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

示例 1:

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

示例 2:

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

提示:

  • n == edges.length
  • 2 <= n <= 105
  • -1 <= edges[i] < n
  • edges[i] != i

思路

​ 不要被难度级别“困难”吓倒,其实读懂题目后,好像也没那么难。题意说人话就是,有向图中每个节点最多只有1条出边,求这个图中最大的环包含的节点数量,如果没有环,则返回-1。

​ 题目并不保证整个图是全部连通的,所以,我们可以先把这个图分成若干个不连通的部分,在每个部分内部,是连通的。那每个部分有如下三种情况

  • 无环,是若干个存在公共节点的链表
  • 有环,而且所有节点都在环内
  • 有环,部分节点在环内,部分节点在环外

​ 因为题目保证了每个节点最多只有1条出边,所以确定了起始点后,往后遍历的路径是唯一的。对于无环的情况,我们无论从哪个节点开始遍历,最后都不会成环;对于情况2和情况3有环的情况,无论我们从哪个节点开始遍历,最终一定可以遍历到环内的节点,且可以重复走到环内的每个节点。

​ 所以,我们可以采取这样的策略,每次遍历一个节点,全局时间time++:外层,从下标0n-1作为每个连通部分的起点进行遍历,内层,通过firstVisitTime[]数组来记录这个节点第一次被遍历到的时间,如果时间是0,证明这个节点没有被遍历过。另外,我们还需要一个变量记录每个连通部分第一次被遍历到的时间partBegin,如果firstVisitTime[i] >= partBegin,证明确实是在这个连通部分遍历的,那么当前时间减去firstVisitTime[i] 就是这个环的大小了。

图解

代码

public int longestCycle(int[] edges) {
int ans = -1;
int time = 0;
int[] firstVisitTime = new int[edges.length];
for (int i = 0; i < edges.length; i++) {
int index = i;
int partBegin = time;
while (index != -1 && firstVisitTime[index] == 0) {
firstVisitTime[index] = time++;
index = edges[index];
}
if (index != -1 && firstVisitTime[index] >= partBegin) {
ans = Integer.max(ans, time - firstVisitTime[index]);
}
}
return ans;
}

耗时

leetcode每日一题:图中的最长环的更多相关文章

  1. 【python】Leetcode每日一题-森林中的兔子

    [python]Leetcode每日一题-森林中的兔子 [题目描述] 森林中,每个兔子都有颜色.其中一些兔子(可能是全部)告诉你还有多少其他的兔子和自己有相同的颜色.我们将这些回答放在 answers ...

  2. LeetCode每日一题打卡组队监督!刷题群!

    近 2000 人已经加入共同刷题啦! 群友每天都会在群里给大家讲解算法题 每周日「负雪明烛」组织直播讲题 我相信来看我博客的大部分人都是通过LeetCode刷题过来的.最近发现LeetCode中文网站 ...

  3. 【python】Leetcode每日一题-寻找旋转排序数组中的最小元素

    [python]Leetcode每日一题-寻找旋转排序数组中的最小元素 [题目描述] 已知一个长度为 n 的数组,预先按照升序排列,经由 1 到 n 次 旋转 后,得到输入数组.例如,原数组nums ...

  4. 【python】Leetcode每日一题-删除有序数组中的重复项

    [python]Leetcode每日一题-删除有序数组中的重复项 [题目描述] 给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使每个元素 最多出现一次 ,返回删除后数组的新长度. 不要 ...

  5. [LeetCode每日一题]153.寻找旋转排序数组中的最小值

    [LeetCode每日一题]153.寻找旋转排序数组中的最小值 问题 已知一个长度为 n 的数组,预先按照升序排列,经由 1 到 n 次 旋转 后,得到输入数组.例如,原数组 nums = [0,1, ...

  6. [LeetCode每日一题]80. 删除有序数组中的重复项 II

    [LeetCode每日一题]80. 删除有序数组中的重复项 II 问题 给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使每个元素 最多出现两次 ,返回删除后数组的新长度. 不要使用额外 ...

  7. 【python】Leetcode每日一题-寻找旋转排序数组中的最小元素2

    [python]Leetcode每日一题-寻找旋转排序数组中的最小元素2 [题目描述] 已知一个长度为 n 的数组,预先按照升序排列,经由 1 到 n 次 旋转 后,得到输入数组.例如,原数组nums ...

  8. 【python】Leetcode每日一题-删除有序数组中的重复项2

    [python]Leetcode每日一题-删除有序数组中的重复项2 [题目描述] 给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使每个元素 最多出现两次 ,返回删除后数组的新长度. 不 ...

  9. 【python】Leetcode每日一题-删除排序链表中的重复元素

    [python]Leetcode每日一题-删除排序链表中的重复元素 [题目描述] 存在一个按升序排列的链表,给你这个链表的头节点 head ,请你删除所有重复的元素,使每个元素 只出现一次 . 返回同 ...

  10. 【python】Leetcode每日一题-删除排序链表中的重复元素2

    [python]Leetcode每日一题-删除排序链表中的重复元素2 [题目描述] 存在一个按升序排列的链表,给你这个链表的头节点 head ,请你删除链表中所有存在数字重复情况的节点,只保留原始链表 ...

随机推荐

  1. ASP.NET Core - 日志记录系统(二)

    本篇接着上一篇 [ASP.NET Core - 日志记录系统(一)] 往下讲,所以目录不是从 1 开始的. 2.4 日志提供程序 2.4.1 内置日志提供程序 ASP.NET Core 包括以下日志记 ...

  2. 大语言模型(LLMs)隐私保护技术综述学习

    链接:https://mp.weixin.qq.com/s/PCVHPxCwuciTR2BQCsAl4Q 原文:https://arxiv.org/abs/2408.05212

  3. JVM:方法区、堆

    https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html#jvms-2.6.2

  4. web95 比较麻烦的interval绕过

    审计 include("flag.php"); highlight_file(__FILE__); if(isset($_GET['num'])){ $num = $_GET['n ...

  5. uni-app发布体验版本后授权登录很卡

    今天uni-app发布了一个体验版本, 但是我发现扫码登录后: 非常的卡顿在授权登录的时候: 但是在我的模拟器开发的时候, 是非常的流畅的. 没有一点儿的卡顿: 在真机上预览的时候也是非常的流畅的: ...

  6. MySQL SQL调优之索引

    本篇记录MySQL的索引知识学习笔记,也方便自己以后查找复习 一.索引的概念MySQL官方给出的索引定义:索引(Index)是帮助MySQL高效获取数据的数据结构.所以说索引就是排好序的快速查找数据结 ...

  7. 【忍者算法】从风扇叶片到数组轮转:探索轮转数组问题|LeetCode 189 轮转数组

    从风扇叶片到数组轮转:探索轮转数组问题 生活中的算法 想象你在看一个风扇缓缓转动,每次转动三个叶片的距离.原本在上方的叶片转到了右侧,原本在右侧的叶片转到了下方...这就是一个生动的轮转过程.再比如, ...

  8. redis如何设置密码

    密码设置 这里简单介绍一下redis如何设置密码redis密码设置有两种方式,一种需要重启redis服务,一种不需要重启redis服务. 首先,介绍一下需要重启redis服务的设置方式即找到redis ...

  9. 解决tsc编译器版本过低问题

    我们知道,tsc是TypeScript的编译器,可以将TypeScript脚本(.ts文件)编译为JavaScript脚本(.js文件).根据约定,TypeScript脚本文件使用.ts后缀名,Jav ...

  10. linux mint下安装截图工具

    在linux下尝试了多款截图工具,综合下来,觉得shutter是最好用的,推荐大家使用. Shutter 是一个强大的截图工具,强大的功能集成到一个直观的简洁界面,应用程序自带多个区域截图(如全屏,选 ...