802 找到最终的安全状态

2024-03-28 04:44
文章标签 安全 状态 找到 最终 802

本文主要是介绍802 找到最终的安全状态,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题目

有一个有 n 个节点的有向图,节点按 0 到 n - 1 编号。图由一个 索引从 0 开始 的 2D 整数数组 graph表示, graph[i]是与节点 i 相邻的节点的整数数组,这意味着从节点 i 到 graph[i]中的每个节点都有一条边。

如果一个节点没有连出的有向边,则该节点是 终端节点 。如果从该节点开始的所有可能路径都通向 终端节点 ,则该节点为 安全节点 。

返回一个由图中所有 安全节点 组成的数组作为答案。答案数组中的元素应当按 升序 排列。

示例 1:

Illustration of graph

输入: graph = [[1,2],[2,3],[5],[0],[5],[],[]]
输出: [2,4,5,6]
解释: 示意图如上。
节点 5 和节点 6 是终端节点,因为它们都没有出边。
从节点 2、4、5 和 6 开始的所有路径都指向节点 5 或 6 。

解法

这道题的本质究其根本就是寻找有无环路,如果一道题目需要检测图中是否存在环路,算法如下:

  1. 深度优先搜索(DFS) :通过深度优先搜索遍历图的所有节点,并标记节点状态,如果在搜索过程中发现某个节点已经被访问过且还未完成遍历,则存在环路。
  2. 广度优先搜索(BFS) :通过广度优先搜索遍历图的所有节点,并检测是否存在环路。
  3. 拓扑排序:拓扑排序是一种特殊的排序算法,它可以对有向无环图进行排序,如果图中存在环路,则无法进行拓扑排序。
  4. 并查集:并查集也可以用于检测图中是否存在环路,特别适用于无向图

BFS + 拓扑序列 + 逆转图

class Solution {int N = 100010, M = N * 2 + 10, idx = 0;int[] ne = new int[M], e = new int[M], h = new int[N], cnt = new int[N];public void add(int a, int b) {e[idx] = b;ne[idx] = h[a];h[a] = idx ++;}public List<Integer> eventualSafeNodes(int[][] graph) {// 首先想到的是拓扑序列,因为终端节点意味着没有出度,// 能所有边都到达终端节点的即为安全节点,所以可以想逆转图,即出度和入度转换Arrays.fill(h, -1);int n = graph.length;for(int i = 0;i < n;i ++) {for(int j : graph[i]) {add(j, i); // 转换出度入度cnt[i] ++;}}Deque<Integer> de = new ArrayDeque<>();  // 注意这个双向队列for(int i = 0;i < n;i ++) {if(cnt[i] == 0) {de.addFirst(i);}}while(!de.isEmpty()) {int t = de.pollLast();for(int i = h[t];i != -1;i = ne[i]) {int j = e[i];cnt[j] --;if(cnt[j] == 0) {de.addFirst(j);}}}ArrayList<Integer> ans = new ArrayList<>();for(int i = 0;i < n;i ++) {if(cnt[i] == 0) {ans.add(i);}}return ans;}
}

三色图

class Solution {// 三色标记法,0 --- 未被访问过, 1 --- 正在访问中, 2 --- 已经访问过public List<Integer> eventualSafeNodes(int[][] graph) {int n = graph.length; int[] color = new int[n];List<Integer> ans = new ArrayList<Integer>();for(int i = 0;i < n;i ++) {if(isSafe(graph, color, i)) {ans.add(i);}}return ans;}public boolean isSafe(int[][] graph, int[] color, int x) {if(color[x] != 0) {return color[x] == 2;}color[x] = 1;for(int y : graph[x]) {if(!isSafe(graph, color, y)) {return false;}}color[x] = 2;return true;}
}

这篇关于802 找到最终的安全状态的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/854483

相关文章

JWT + 拦截器实现无状态登录系统

《JWT+拦截器实现无状态登录系统》JWT(JSONWebToken)提供了一种无状态的解决方案:用户登录后,服务器返回一个Token,后续请求携带该Token即可完成身份验证,无需服务器存储会话... 目录✅ 引言 一、JWT 是什么? 二、技术选型 三、项目结构 四、核心代码实现4.1 添加依赖(pom

C#文件复制异常:"未能找到文件"的解决方案与预防措施

《C#文件复制异常:未能找到文件的解决方案与预防措施》在C#开发中,文件操作是基础中的基础,但有时最基础的File.Copy()方法也会抛出令人困惑的异常,当targetFilePath设置为D:2... 目录一个看似简单的文件操作问题问题重现与错误分析错误代码示例错误信息根本原因分析全面解决方案1. 确保

深度解析Nginx日志分析与499状态码问题解决

《深度解析Nginx日志分析与499状态码问题解决》在Web服务器运维和性能优化过程中,Nginx日志是排查问题的重要依据,本文将围绕Nginx日志分析、499状态码的成因、排查方法及解决方案展开讨论... 目录前言1. Nginx日志基础1.1 Nginx日志存放位置1.2 Nginx日志格式2. 499

Nginx安全防护的多种方法

《Nginx安全防护的多种方法》在生产环境中,需要隐藏Nginx的版本号,以避免泄漏Nginx的版本,使攻击者不能针对特定版本进行攻击,下面就来介绍一下Nginx安全防护的方法,感兴趣的可以了解一下... 目录核心安全配置1.编译安装 Nginx2.隐藏版本号3.限制危险请求方法4.请求限制(CC攻击防御)

Java 线程安全与 volatile与单例模式问题及解决方案

《Java线程安全与volatile与单例模式问题及解决方案》文章主要讲解线程安全问题的五个成因(调度随机、变量修改、非原子操作、内存可见性、指令重排序)及解决方案,强调使用volatile关键字... 目录什么是线程安全线程安全问题的产生与解决方案线程的调度是随机的多个线程对同一个变量进行修改线程的修改操

python3如何找到字典的下标index、获取list中指定元素的位置索引

《python3如何找到字典的下标index、获取list中指定元素的位置索引》:本文主要介绍python3如何找到字典的下标index、获取list中指定元素的位置索引问题,具有很好的参考价值,... 目录enumerate()找到字典的下标 index获取list中指定元素的位置索引总结enumerat

Java中常见队列举例详解(非线程安全)

《Java中常见队列举例详解(非线程安全)》队列用于模拟队列这种数据结构,队列通常是指先进先出的容器,:本文主要介绍Java中常见队列(非线程安全)的相关资料,文中通过代码介绍的非常详细,需要的朋... 目录一.队列定义 二.常见接口 三.常见实现类3.1 ArrayDeque3.1.1 实现原理3.1.2

IIS 7.0 及更高版本中的 FTP 状态代码

《IIS7.0及更高版本中的FTP状态代码》本文介绍IIS7.0中的FTP状态代码,方便大家在使用iis中发现ftp的问题... 简介尝试使用 FTP 访问运行 Internet Information Services (IIS) 7.0 或更高版本的服务器上的内容时,IIS 将返回指示响应状态的数字代

使用Python实现IP地址和端口状态检测与监控

《使用Python实现IP地址和端口状态检测与监控》在网络运维和服务器管理中,IP地址和端口的可用性监控是保障业务连续性的基础需求,本文将带你用Python从零打造一个高可用IP监控系统,感兴趣的小伙... 目录概述:为什么需要IP监控系统使用步骤说明1. 环境准备2. 系统部署3. 核心功能配置系统效果展

JAVA保证HashMap线程安全的几种方式

《JAVA保证HashMap线程安全的几种方式》HashMap是线程不安全的,这意味着如果多个线程并发地访问和修改同一个HashMap实例,可能会导致数据不一致和其他线程安全问题,本文主要介绍了JAV... 目录1. 使用 Collections.synchronizedMap2. 使用 Concurren