题目

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. C#中如何使用异步编程

    在 C# 中,异步编程主要通过 async 和 await 关键字来实现.异步编程的目的是让程序在执行耗时操作(如 I/O 操作.网络请求等)时不会阻塞主线程,从而提高程序的性能. 1. 异步编程的核 ...

  2. .NET Core GC标记阶段(mark_phase)底层原理浅谈

    简介 C# 采用基于代的回收机制,并使用了更复杂的 链式跟踪算法 来识别对象是否为垃圾. GC触发的原因 截至到.NET 8,GC触发的原因有18种 enum gc_reason { reason_a ...

  3. VBA 解析 json

    Sub Macro1() Debug.Print "999" Dim FilePath, strData FilePath = "C:\Git\Test\JenProje ...

  4. Java接口-详解

    一.基本概念 接口(Interface),在JAVA编程语言中是一个抽象类型,是抽象方法的集合.接口通常以interface来声明.一个类通过继承接口的方式,从而来继承接口的抽象方法. 如果一个类只由 ...

  5. 在没有网关的IP地址上编写路由,实现另一个网段可以访问到该主机

    应用场景:该主机两个网卡分别对应两个IP地址 192.168.1.2网段为医保网,并且主机使用了改网段的的网关.192.168.100.99网段地址为互联网地址,没有使用该网段的网关. 我们开发小组通 ...

  6. Jenkins执行Shell脚本超时错误处理指南

    Jenkins执行Shell脚本超时错误处理指南 在使用Jenkins进行自动化测试时,经常会遇到需要执行Shell脚本的情况.然而,当Shell脚本执行时间过长,超过了Jenkins配置的超时限制时 ...

  7. 对外提供API,通过appId、appSecret、sign秘钥对接口做鉴权

    一.背景 在接口开发过程中,我们通常不能暴露一个接口给第三方随便调用,要对第三方发来参数进行校验,看是不是具有访问权限. 名词介绍: 1.appId: 应用id,用户自定义命名,如:*-access- ...

  8. Maven配置多数据源

    一.配置文件 修改maven配置文件,用户目录下.m2文件夹中的setting.xml,内容如下 <?xml version="1.0" encoding="UTF ...

  9. flutter-全局监听路由

    main.dart navigatorObservers: [ MyApp.routeObserver, GLObserver(),//全局监听路由 ], router_listener.dart c ...

  10. Scrapy css选择器提取数据

    原文学习链接:http://www.scrapyd.cn/doc/185.html 一. 标签属性值的提取 href的值URL的提取:这是最常见的,我们要进入下一页.或是打开内容页--都少不了URL值 ...