【LeetCode每日一题】——802.找到最终的安全状态
文章目录
- 一【题目类别】
- 二【题目难度】
- 三【题目编号】
- 四【题目描述】
- 五【题目示例】
- 六【题目提示】
- 七【解题思路】
- 八【时空频度】
- 九【代码实现】
- 十【提交结果】
一【题目类别】
- 图
二【题目难度】
- 中等
三【题目编号】
- 802.找到最终的安全状态
四【题目描述】
- 有一个有
n
个节点的有向图,节点按0
到n - 1
编号。图由一个 索引从0
开始 的 2D 整数数组graph
表示,graph[i]
是与节点i
相邻的节点的整数数组,这意味着从节点i
到graph[i]
中的每个节点都有一条边。 - 如果一个节点没有连出的有向边,则该节点是 终端节点 。如果从该节点开始的所有可能路径都通向 终端节点 ,则该节点为 安全节点 。
- 返回一个由图中所有 安全节点 组成的数组作为答案。答案数组中的元素应当按 升序 排列。
五【题目示例】
-
示例 1:
- 输入:graph = [[1,2],[2,3],[5],[0],[5],[],[]]
- 输出:[2,4,5,6]
- 解释:示意图如上。
- 节点 5 和节点 6 是终端节点,因为它们都没有出边。
- 从节点 2、4、5 和 6 开始的所有路径都指向节点 5 或 6 。
-
示例 2:
- 输入:graph = [[1,2,3,4],[1,2],[3,4],[0,4],[]]
- 输出:[4]
- 解释:
- 只有节点 4 是终端节点,从节点 4 开始的所有路径都通向节点 4 。
六【题目提示】
- n = = g r a p h . l e n g t h n == graph.length n==graph.length
- 1 < = n < = 1 0 4 1 <= n <= 10^4 1<=n<=104
- 0 < = g r a p h [ i ] . l e n g t h < = n 0 <= graph[i].length <= n 0<=graph[i].length<=n
- 0 < = g r a p h [ i ] [ j ] < = n − 1 0 <= graph[i][j] <= n - 1 0<=graph[i][j]<=n−1
- g r a p h [ i ] graph[i] graph[i] 按严格递增顺序排列。
- 图中可能包含自环。
- 图中边的数目在范围 [ 1 , 4 ∗ 1 0 4 ] [1, 4 * 10^4] [1,4∗104] 内。
七【解题思路】
- 利用拓扑排序的思想解决该问题
- 我们首先构建一个反向图,即假如之前
i -> j
,那么反向图就变为j -> i
,反向图的目的是用来后续计算出度来找到终端节点 - 同时构建原图的出度数组,后续就会用该数组来找到安全节点
- 然后将得到的所有终端节点都入队列,后续操作该队列即可得到所有终端节点
- 然后将得到的安全节点(所有终端节点都是安全节点)保存到集合中
- 然后通过逆向拓扑排序计算得到安全节点:
- 首先从队列中取出一个安全节点
- 然后查看它的邻接节点
- 然后将邻接节点的出度减
1
- 如果此时出度为
0
,那么说明其为安全节点,将其入队列和集合中
- 然后将邻接节点的出度减
- 具体细节可以参考下面的代码
- 最后返回结果即可
八【时空频度】
- 时间复杂度: O ( m + n ) O(m + n) O(m+n), m m m为图的节点数, n n n为图的边数
- 空间复杂度: O ( m + n ) O(m + n) O(m+n), m m m为图的节点数, n n n为图的边数
九【代码实现】
- Java语言版
class Solution {public List<Integer> eventualSafeNodes(int[][] graph) {// 图中节点的个数int n = graph.length;// 用来存储反向图List<List<Integer>> reverseGraph = new ArrayList<>();for (int i = 0; i < n; i++) {reverseGraph.add(new ArrayList<>());}// 每个节点的出度int[] outDegree = new int[n];// 构建反向图和出度数组for (int i = 0; i < n; i++) {outDegree[i] = graph[i].length;for (int neighbor : graph[i]) {reverseGraph.get(neighbor).add(i);}}// 初始化队列,将所有终端节点(出度为0的节点)加入队列Queue<Integer> queue = new LinkedList<>();for (int i = 0; i < n; i++) {if (outDegree[i] == 0) {queue.offer(i);}}// 用集合存储安全节点Set<Integer> safeNodes = new HashSet<>(queue);// 逆向拓扑排序while (!queue.isEmpty()) {int node = queue.poll();for (int neighbor : reverseGraph.get(node)) {outDegree[neighbor]--;if (outDegree[neighbor] == 0) {safeNodes.add(neighbor);queue.offer(neighbor);}}}// 返回安全节点的升序列表List<Integer> res = new ArrayList<>(safeNodes);Collections.sort(res);return res;}
}
- Python语言版
class Solution:def eventualSafeNodes(self, graph: List[List[int]]) -> List[int]:# 图中节点的个数n = len(graph)# 用来存储反向图reverse_graph = defaultdict(list)# 每个节点的出度out_degree = [0] * n# 构建反向图和出度数组for i, neighboors in enumerate(graph):out_degree[i] = len(neighboors)for neighboor in neighboors:reverse_graph[neighboor].append(i)# 初始化队列,将所有终端节点(出度为0的节点)加入队列queue = deque(i for i in range(n) if out_degree[i] == 0)# 用集合存储安全节点safe_nodes = set(queue)# 逆向拓扑排序while queue:node = queue.popleft()for neighboor in reverse_graph[node]:out_degree[neighboor] -= 1if out_degree[neighboor] == 0:safe_nodes.add(neighboor)queue.append(neighboor)# 返回安全节点的升序列表return sorted(safe_nodes)
- C++语言版
class Solution {
public:vector<int> eventualSafeNodes(vector<vector<int>>& graph) {// 图中节点的个数int n = graph.size();// 用来存储反向图vector<vector<int>> reverseGraph(n);// 每个节点的出度vector<int> outDegree(n, 0);// 构建反向图和出度数组for (int i = 0; i < n; i++) {outDegree[i] = graph[i].size();for (int neighbor : graph[i]) {reverseGraph[neighbor].push_back(i);}}// 初始化队列,将所有终端节点(出度为0的节点)加入队列queue<int> q;// 用集合存储安全节点unordered_set<int> safeNodes;for (int i = 0; i < n; i++) {if (outDegree[i] == 0) {q.push(i);safeNodes.insert(i);}}// 逆向拓扑排序while (!q.empty()) {int node = q.front();q.pop();for (int neighbor : reverseGraph[node]) {outDegree[neighbor]--;if (outDegree[neighbor] == 0) {safeNodes.insert(neighbor);q.push(neighbor);}}}// 返回安全节点的升序列表vector<int> res(safeNodes.begin(), safeNodes.end());sort(res.begin(), res.end());return res;}
};
十【提交结果】
-
Java语言版
-
Python语言版
-
C++语言版
相关文章:

【LeetCode每日一题】——802.找到最终的安全状态
文章目录 一【题目类别】二【题目难度】三【题目编号】四【题目描述】五【题目示例】六【题目提示】七【解题思路】八【时空频度】九【代码实现】十【提交结果】 一【题目类别】 图 二【题目难度】 中等 三【题目编号】 802.找到最终的安全状态 四【题目描述】 有一个有…...

kafka安装部署--详细教程
2.1 安装部署 每次进入 linux 都会自动进入 base 环境,如何关闭 base conda deactivate 手动关闭 conda config --set auto_activate_base false 关闭自动进入 2.1.1 集群规划 bigdata01 bigdata02 bigdata03 zk zk zk kafka kafka kafka 2.1.2 集群部…...

CMD 查询python 出现 No pyvenv.cfg file 很奇怪 2024/11/9
CMD 查询python 出现 No pyvenv.cfg file 很奇怪 查询得到我有很多个...........版本 删除这个变量就不会 因为 没有安装软件 跳转到 Windows 商店 再把主要使用的python路径置顶 现在运行cmd查询 对比之前的图片 可以发现 这一条商店的没有了! 完整测试效果,问题解决了!...

learnopencv系列二:U2-Net/IS-Net图像分割(背景减除)算法、使用背景减除实现视频转ppt应用
文章目录 一、视频转幻灯片应用1.1 什么是背景减除?1.1.1 背景减除简介1.1.2 bgslibrary 1.2 OpenCV背景减除技术1.3 差异哈希1.3.1 图像哈希技术1.3.2 dHash算法1.3.3 图像哈希的速度和准确性测试 1.4 视频转幻灯片应用的工作流程1.5 项目代码1.5.1 环境准备1.5.2 …...

linux命令详解,文件系统权限相关
文件系统权限相关 linux系统中一切都是文件 查看权限 Is -la /etc/passwd更改文件所有者 chown root file修改文件权限 sudo chmod urwx,grw,o-r file sudo chmod ux,gtw,o-r file chmod 400 <file>一、Linux系统中一切都是文件 在linux系统中,几乎所有的…...
2024-11-5 学习人工智能的Day22 openCV(4)
face_recognition 介绍 face_recognition 是一个非常流行的 Python 库,专门用于人脸识别任务。它基于 dlib 库和 HOG(Histogram of Oriented Gradients)特征以及深度学习模型,提供了简单易用的接口来进行人脸检测、面部特征点定位…...

JavaScript 网页设计详解教程
JavaScript 网页设计详解教程 引言 JavaScript 是一种广泛使用的编程语言,主要用于网页开发。它使得网页具有动态交互性,能够响应用户的操作。随着前端开发的不断发展,JavaScript 已成为现代网页设计中不可或缺的一部分。本文将详细介绍 Ja…...

技术复杂性导致估算不准确?5大对策
技术复杂性引发的估算不准确可能导致成本超出预算,不当的资源分配则可能造成人力浪费或关键任务缺乏必要支持,进而影响客户满意度和市场竞争力,增加项目失败的风险。而有效避免因技术复杂性导致的估算不准确问题,可以显著提升项目…...

【JavaEE初阶 — 多线程】死锁的产生原因和解决方法
目录 死锁 1.构成死锁的场景 (1) 一个线程一把锁 问题描述 解决方案(可重入锁) (2) 两个线程两把锁 问题描述 (3)N个线程 M把锁 哲学家就餐问题 2.死锁的四个必要条件 3.如何解决死锁问题 (1)避免出现请求和保持 (2)打破多个线程的循环等待关系 死锁…...
mapper.xml 使用大于号、小于号示例
<mapper namespace"com.example.EmployeeMapper"><!-- 更新employee_absent_resign_statistics表中的pre_work_date --><update id"updatePreWorkDate"><
深入了解决策树:机器学习中的经典算法
✅作者简介:2022年博客新星 第八。热爱国学的Java后端开发者,修心和技术同步精进。 🍎个人主页:Java Fans的博客 🍊个人信条:不迁怒,不贰过。小知识,大智慧。 💞当前专栏…...
Flutter鸿蒙next 的 Sliver 实现自定义滚动效果
Flutter 提供了一些非常强大的滚动组件,如 ListView、GridView 等,它们可以在滑动时自动处理内容的显示和滚动。但当我们需要更复杂的滚动效果时,Sliver 组件便是一个强大的工具。通过自定义 Sliver,我们可以实现高度定制化的滚动…...
杨中科 .Net Core 笔记 DI 依赖注入
提到依赖不得不提到,控制反转(Inversion of Control,IOC)这个概念,简单的来讲就是将控制对象的权限交给框架,不再手动完成。IOC实现方式有2种: 1、服务定位器(ServiceLocator),主动…...

【RocketMQ】无法访问此网站 http://XXX:10080/ ERR_UNSAFE_PORT
安装完rocketmq-dashboard。打开浏览器访问地址。 问题提示: 无法访问此网站 网址为 http://192.168.22.197:10080/ 的网页可能暂时无法连接,或者它已永久性地移动到了新网址。 ERR_UNSAFE_PORT 无法访问10080端口的网站通常是由于Chrome浏览器的安…...
pipreqs:快速准确生成当前项目的requirements.txt,还有和freeze的对比
大家好,这里是程序员晚枫。 今天给大家推荐一个快速生成requirements.txt的小工具:pipreqs。 什么是requirements.txt? 我们在开发Python项目的时候,需要用到requirements.txt来管理项目中使用的第三方库。 当我们把项目部署到…...
Spark 中的 RDD 分区的设定规则与高阶函数、Lambda 表达式详解
Spark 的介绍与搭建:从理论到实践_spark环境搭建-CSDN博客 Spark 的Standalone集群环境安装与测试-CSDN博客 PySpark 本地开发环境搭建与实践-CSDN博客 Spark 程序开发与提交:本地与集群模式全解析-CSDN博客 Spark on YARN:Spark集群模式…...

redis十大数据类型
文章目录 一、redis字符串(String)set key value同时获取或设置多个键值获取指定区间范围内的值数字增减获取字符串长度和内容追加分布式锁getset(先get再set) 二、redis列表(List)通过索引获取列表中的元素…...
国内AI工具复现GPTs效果详解
国内AI工具复现GPTs效果详解 引言 近年来,随着人工智能技术的飞速发展,大型语言模型(LLM)逐渐成为研究和应用的热点。GPTs(Generative Pre-trained Transformer)系列模型,特别是GPT-4的推出&a…...
【学习笔记】SAP ABAP——OPEN SQL(一)【INTO语句】
【INTO语句】 结构体插入(插入一条语句时) SELECT...INTO [CORRESPONDING FIELDS OF] <wa> FROM <db> WHERE <condition>.内表插入(插入多条语句时) SELECT...INTO|APPENDING [CORRESPONDING FIELDS OF] TABLE <itab>FROM <db> WHERE <con…...

vscode使用之vscode-server离线安装
最近因为想要使用AI工具开始使用vscode,但是在内网使用vscode通过SSH连接虚拟机的centos远程目录却出现了问题,始终连不上,查看原因是centos没有安装vscode-server,网上找各个教程离线安装vscode-code除了浪费时间没有任何收获&am…...

Spark 之 入门讲解详细版(1)
1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室(Algorithms, Machines, and People Lab)开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目,8个月后成为Apache顶级项目,速度之快足见过人之处&…...
IGP(Interior Gateway Protocol,内部网关协议)
IGP(Interior Gateway Protocol,内部网关协议) 是一种用于在一个自治系统(AS)内部传递路由信息的路由协议,主要用于在一个组织或机构的内部网络中决定数据包的最佳路径。与用于自治系统之间通信的 EGP&…...
在四层代理中还原真实客户端ngx_stream_realip_module
一、模块原理与价值 PROXY Protocol 回溯 第三方负载均衡(如 HAProxy、AWS NLB、阿里 SLB)发起上游连接时,将真实客户端 IP/Port 写入 PROXY Protocol v1/v2 头。Stream 层接收到头部后,ngx_stream_realip_module 从中提取原始信息…...

相机从app启动流程
一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...

华硕a豆14 Air香氛版,美学与科技的馨香融合
在快节奏的现代生活中,我们渴望一个能激发创想、愉悦感官的工作与生活伙伴,它不仅是冰冷的科技工具,更能触动我们内心深处的细腻情感。正是在这样的期许下,华硕a豆14 Air香氛版翩然而至,它以一种前所未有的方式&#x…...
A2A JS SDK 完整教程:快速入门指南
目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库ÿ…...

【笔记】WSL 中 Rust 安装与测试完整记录
#工作记录 WSL 中 Rust 安装与测试完整记录 1. 运行环境 系统:Ubuntu 24.04 LTS (WSL2)架构:x86_64 (GNU/Linux)Rust 版本:rustc 1.87.0 (2025-05-09)Cargo 版本:cargo 1.87.0 (2025-05-06) 2. 安装 Rust 2.1 使用 Rust 官方安…...
MySQL JOIN 表过多的优化思路
当 MySQL 查询涉及大量表 JOIN 时,性能会显著下降。以下是优化思路和简易实现方法: 一、核心优化思路 减少 JOIN 数量 数据冗余:添加必要的冗余字段(如订单表直接存储用户名)合并表:将频繁关联的小表合并成…...

Proxmox Mail Gateway安装指南:从零开始配置高效邮件过滤系统
💝💝💝欢迎莅临我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:「storms…...
提升移动端网页调试效率:WebDebugX 与常见工具组合实践
在日常移动端开发中,网页调试始终是一个高频但又极具挑战的环节。尤其在面对 iOS 与 Android 的混合技术栈、各种设备差异化行为时,开发者迫切需要一套高效、可靠且跨平台的调试方案。过去,我们或多或少使用过 Chrome DevTools、Remote Debug…...