LeetCode: 1971. 寻找图中是否存在路径

寻找图中是否存在路径

原题

有一个具有 n 个顶点的 双向 图,其中每个顶点标记从 0n - 1(包含 0n - 1)。图中的边用一个二维整数数组 edges 表示,其中 edges[i] = [ui, vi] 表示顶点 ui 和顶点 vi 之间的双向边。 每个顶点对由 最多一条 边连接,并且没有顶点存在与自身相连的边。

请你确定是否存在从顶点 source 开始,到顶点 destination 结束的 有效路径

给你数组 edges 和整数 nsourcedestination,如果从 sourcedestination 存在 有效路径 ,则返回 true,否则返回 false

示例 1:(图片转存自LeetCode)

图片来源:LeetCode

输入:n = 3, edges = [[0,1],[1,2],[2,0]], source = 0, destination = 2
输出:true
解释:存在由顶点 0 到顶点 2 的路径:
- 0 → 1 → 2 
- 0 → 2

示例 2:

img

输入:n = 6, edges = [[0,1],[0,2],[3,5],[5,4],[4,3]], source = 0, destination = 5
输出:false
解释:不存在由顶点 0 到顶点 5 的路径.

提示:

  • 1 <= n <= 2 * 105
  • 0 <= edges.length <= 2 * 105
  • edges[i].length == 2
  • 0 <= ui, vi <= n - 1
  • ui != vi
  • 0 <= source, destination <= n - 1
  • 不存在重复边
  • 不存在指向顶点自身的边
class Solution {public boolean validPath(int n, int[][] edges, int source, int destination) {}
}

解题思路

  1. 将图的边列表(二维整数数组 edges)转化为图的邻接表形式,以便快速访问每个节点的相邻节点信息。由于节点编号从 0n-1 连续,故采用数组而非 HashMap 进行存储。
  2. 使用[[深度优先搜索]]递归地进行图的遍历。在遍历过程中,需要避免重复访问已经访问过的节点,因此使用一个 visited 数组来记录哪些节点已经被访问过。
  3. 终止条件:
    • 如果在遍历过程中找到了 destination,则可以立即返回 true,表示路径存在。
    • 如果遍历了所有可能的路径都没有找到 destination,则返回 false,表示路径不存在。

代码示例

class Solution {public boolean validPath(int n, int[][] edges, int source, int destination) {// 如果起点和终点是同一个点,直接返回 trueif (source == destination) return true;// 构建邻接表,用数组表示图List<Integer>[] graph = new ArrayList[n];for (int i = 0; i < n; i ++) {graph[i] = new ArrayList<>();}// 填充邻接表for (int[] edge : edges) {int fromNode = edge[0];int toNode = edge[1];graph[fromNode].add(toNode);graph[toNode].add(fromNode);}// 创建访问标记数组boolean[] visited = new boolean[n];// 使用 DFS 检查是否存在从 source 到 destination 的路径return dfs(graph, visited, source, destination);}private boolean dfs(List<Integer>[] graph, boolean[] visited, int node, int destination) {// 如果当前节点是目标节点,返回 trueif (node == destination) return true;// 标记当前节点为已访问visited[node] = true;// 遍历所有相邻节点for (int neighbor : graph[node]) {// 如果相邻节点没有访问过,进行递归 DFSif (!visited[neighbor]) {if (dfs(graph, visited, neighbor, destination)) {// 找到能到达终点的路径就返回 truereturn true;}}}// 所有路径都不能到达终点,返回 falsereturn false;}
}

优化思路

这是一个经典的并查集问题。通过并查集的数据结构,可以高效地判断两个节点是否连通。每次将两个节点的根节点连接在一起,最终只需检查 sourcedestination 是否有相同的根节点即可。

优化后代码

class Solution {private int[] parent;private int[] rank; // 树的高度数组public boolean validPath(int n, int[][] edges, int source, int destination) {parent = new int[n];rank = new int[n];// 初始化并查集:每个节点的父节点为自己,rank 初始化为 1for (int i = 0; i < n; i++) {parent[i] = i;rank[i] = 1;}// 遍历所有边,将两个节点连接(即在并查集中合并)for (int[] edge : edges) {union(edge[0], edge[1]);}// 检查起始节点和目标节点是否在同一集合中return find(source) == find(destination);}// 查找某个节点的根节点,同时进行路径压缩private int find(int x) {if (parent[x] != x) { // 如果当前节点不是它自己的父节点,则继续向上查找parent[x] = find(parent[x]);}return parent[x];}// 合并两个集合,使用 rank 优化合并private void union(int x, int y) {int rootX = find(x);int rootY = find(y);if (rootX != rootY) {// 比较两个集合的 rank,rank 小的合并到大的上if (rank[rootX] > rank[rootY]) {parent[rootY] = rootX; // 将 y 的根节点挂到 x 的根节点上} else if (rank[rootX] < rank[rootY]) {parent[rootX] = rootY; // 将 x 的根节点挂到 y 的根节点上} else {parent[rootY] = rootX; // 如果 rank 相同,随意合并,但要增加新根的 rankrank[rootX]++;}}}
}

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

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

相关文章

『功能项目』按钮的打开关闭功能【73】

本章项目成果展示 我们打开上一篇72QFrameWork制作背包界面UGUI的项目&#xff0c; 本章要做的事情是制作打开背包与修改器的打开关闭按钮 首先打开UGUICanvas复制button按钮 重命名为ReviseBtn 修改脚本&#xff1a;UIManager.cs 将修改器UI在UGUICanvas预制体中设置为隐藏 运…

Python--操作列表

1.for循环 1.1 for循环的基本语法 for variable in iterable: # 执行循环体 # 这里可以是任何有效的Python代码块这里的variable是一个变量名&#xff0c;用于在每次循环迭代时临时存储iterable中的下一个元素。 iterable是一个可迭代对象&#xff0c;比如列表&#xff08;…

YOLOv8+注意力机制+PyQt5玉米病害检测系统完整资源集合

资源包含可视化的玉米病害检测系统&#xff0c;基于最新的YOLOv8注意力机制训练的玉米病害检测模型&#xff0c;和基于PyQt5制作的可视玉米病害系统&#xff0c;包含登陆页面和检测页面&#xff0c;该系统可自动检测和识别图片或视频当中出现的七类玉米病害&#xff1a;矮花叶病…

Maya没有Arnold材质球

MAYA 没有Arnold材质球_哔哩哔哩_bilibili

软件测试基础篇

&#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 “尽早的介入测试&#xff0c;遇到问题的解决成本就越低” 随着软件测试技术的发展&#xff0c;测试工作由原来单一的寻找缺陷逐渐发展成为预防缺陷&#xff0c;…

2024.9.26 作业 +思维导图

一、作业 1、什么是虚函数&#xff1f;什么是纯虚函数 虚函数&#xff1a;函数前加关键字virtual&#xff0c;就定义为虚函数&#xff0c;虚函数能够被子类中相同函数名的函数重写 纯虚函数&#xff1a;把虚函数的函数体去掉然后加0&#xff1b;就能定义出一个纯虚函数。 2、基…

前端——实现时钟 附带小例子

创建日期对象 toLocaleDateString() 获取日期 console.log(date.toLocaleDateString()) toLocaleTimeString() 获取时间 console.log(date.toLocaleTimeString()) toLocaleString() 获取日期和时间 console.log(date.toLocaleString()) date.getDay() 获取星期几 周日为…

软件无线电3-微相E316和HackRF实现FM调制解调

前面介绍了基于Matlab、矢量信号器和HackRF One实现射频下的FM调制解调&#xff0c;今天分享的内容是用微相E316替代矢量信号器完成发射工作。注意本文仅用于科研和学习&#xff0c;私自搭建电台属于违法行为。 1.概述 微相E316和HackRF One实现FM调制解调测试框图如1所示&am…

【后端开发】JavaEE初阶—线程的理解和编程实现

前言&#xff1a; &#x1f31f;&#x1f31f;本期讲解多线程的知识哟~~~&#xff0c;希望能帮到屏幕前的你。 &#x1f308;上期博客在这里&#xff1a;【后端开发】JavaEE初阶——计算机是如何工作的&#xff1f;&#xff1f;&#xff1f;-CSDN博客 &#x1f308;感兴趣的小伙…

哈希表(一)

一、基础知识 哈希表的优点&#xff1a; 查找key的时间效率是O&#xff08;1&#xff09; 什么时候要用到哈希表&#xff1a; 查询元素的出现问题&#xff08;是否出现过&#xff0c;是否在集合里&#xff0c;出现次数等&#xff09; 哈希表的三种数据结构&#xff1a; 数组…

4--苍穹外码-SpringBoot项目中分类管理 详解

目录 新增分类 分类分页查询 启用禁用分类 根据类型查询 修改分类 本文介绍SpringBoot项目中的分类管理&#xff0c;操作类似员工管理模块&#xff0c;具体详解可见以下博客&#xff0c;此处给出各部分代码 2--SpringBoot项目中员工管理 详解&#xff08;一&#xff09;-C…

Web端云剪辑解决方案,BS架构私有化部署,安全可控

传统视频制作流程繁琐、耗时&#xff0c;且对专业设备和软件的高度依赖&#xff0c;常常让企业望而却步&#xff0c;美摄科技凭借其强大的技术实力和创新能力&#xff0c;推出了面向企业用户的Web端云剪辑解决方案&#xff0c;为企业提供一站式、高效、便捷的视频生产平台。 B…

[WMCTF2020]Make PHP Great Again 2.01

又是php代码审计,开始吧. 这不用审吧&#xff0c;啊喂. 意思就是我们要利用require_once()函数和传入的file的value去读取flag的内容.&#xff0c;貌似呢require_once()已经被用过一次了&#xff0c;直接读取还不行&#xff0c;看一下下面的知识点. require_once() require…

【C++位图】构建灵活的空间效率工具

目录 位图位图的基本概念如何用位图表示数据位图的基本操作setresettest 封装位图的设计 总结 在计算机科学中&#xff0c;位图&#xff08;Bitmap&#xff09;是一种高效的空间管理数据结构&#xff0c;广泛应用于各种场景&#xff0c;如集合操作、图像处理和资源管理。与传统…

【Docker】基于docker compose部署artifactory-cpp-ce服务

基于docker compose部署artifactory-cpp-ce服务 1 环境准备2 必要文件创建与编写3 拉取镜像-创建容器并后台运行4 访问JFog Artifactory 服务 1 环境准备 docker 以及其插件docker compose &#xff0c;我使用的版本如下图所示&#xff1a; postgresql 的jdbc驱动, 我使用的是…

Qt优秀开源项目之二十三:QSimpleUpdater

QSimpleUpdater是开源的自动升级模块&#xff0c;用于检测、下载和安装更新。 github地址&#xff1a;https://github.com/alex-spataru/QSimpleUpdater QSimpleUpdater目前Star不多&#xff08;911个&#xff09;&#xff0c;但已在很多开源项目看到其身影&#xff0c;比如Not…

Scikit-LearnTensorFlow机器学习实用指南(三):一个完整的机器学习项目【下】

机器学习实用指南(三)&#xff1a;一个完整的机器学习项目【下】 作者&#xff1a;LeonG 本文参考自&#xff1a;《Hands-On Machine Learning with Scikit-Learn & TensorFlow 机器学习实用指南》&#xff0c;感谢中文AI社区ApacheCN提供翻译。 本文全部代码和数据集保存在…

Rust - 字符串:str 与 String

在其他语言中&#xff0c;字符串通常都会比较简单&#xff0c;例如 “hello, world” 就是字符串章节的几乎全部内容了。 但是Rust中的字符串与其他语言有所不同&#xff0c;若带着其他语言的习惯来学习Rust字符串&#xff0c;将会波折不断。 所以最好先忘记脑中已有的关于字…

LiveNVR监控流媒体Onvif/RTSP功能-支持电子放大拉框放大直播视频拉框放大录像视频流拉框放大电子放大

LiveNVR监控流媒体Onvif/RTSP功能-支持电子放大拉框放大直播视频拉框放大录像视频流拉框放大电子放大 1、视频广场2、录像回看3、RTSP/HLS/FLV/RTMP拉流Onvif流媒体服务 1、视频广场 视频广场 -》播放 &#xff0c;左键单击可以拉取矩形框&#xff0c;放大选中的范围&#xff…

汽车总线之----FlexRay总线

Introduction 随着汽车智能化发展&#xff0c;车辆开发的ECU数量不断增加&#xff0c;人们对汽车系统的各个性能方面提出了更高的需求&#xff0c;比如更多的数据交互&#xff0c;更高的传输带宽等。现如今人们广泛接受电子功能来提高驾驶安全性&#xff0c;像ABS防抱死系统&a…