(并查集) 1971. 寻找图中是否存在路径 ——【Leetcode每日一题】

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

难度:简单

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

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

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

示例 1:

在这里插入图片描述

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

  • 0 → 1 → 2
  • 0 → 2
示例 2:

在这里插入图片描述

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

提示

  • 1 < = n < = 2 ∗ 1 0 5 1 <= n <= 2 * 10^5 1<=n<=2105
  • 0 < = e d g e s . l e n g t h < = 2 ∗ 1 0 5 0 <= edges.length <= 2 * 10^5 0<=edges.length<=2105
  • e d g e s [ i ] . l e n g t h = = 2 edges[i].length == 2 edges[i].length==2
  • 0 < = u i , v i < = n − 1 0 <= ui, vi <= n - 1 0<=ui,vi<=n1
  • u i ! = v i ui != vi ui!=vi
  • 0 < = s o u r c e , d e s t i n a t i o n < = n − 1 0 <= source, destination <= n - 1 0<=source,destination<=n1
  • 不存在重复边
  • 不存在指向顶点自身的边

💡思路:并查集

们将图中的每个强连通分量视为一个集合,强连通分量中任意两点均可达,如果两个点 sourcedestination 处在同一个强连通分量中,则两点一定可连通,因此连通性问题可以使用并查集解决。

并查集主要有三个功能:

  1. 寻找根节点,函数:find(int u),也就是判断这个节点的祖先节点是哪个;
  2. 将两个节点****接入到同一个集合,函数:join(int u, int v),将两个节点连在同一个根节点上;
  3. 判断两个节点是否在同一个集合,函数:isSame(int u, int v),就是判断两个节点是不是同一个根节点。

并查集初始化时,n 个顶点分别属于 n 个不同的集合,每个集合只包含一个顶点。初始化之后遍历每条边,由于图中的每条边均为双向边,因此将同一条边连接的两个顶点所在的集合做合并。

遍历所有的边之后,判断顶点 source 和顶点 destination 是否在同一个集合中,如果两个顶点在同一个集合则两个顶点连通,如果两个顶点所在的集合不同则两个顶点不连通。

🍁代码:(C++、Java)

C++

class Solution {
private:vector<int> father;// 初始化并查集void init(int n){father = vector<int>(n, 0);for(int i = 0; i < n; i++) father[i] = i;}// 并查集寻根过程int find(int u){return u == father[u] ? u : father[u] = find(father[u]);}// 判断 u 和 v 是否找到同一个跟bool isSame(int u, int v){return find(u) == find(v);}// 将v->u 这条边加入并查集void join(int u, int v){u = find(u); // 寻找 u 的根v = find(v); // 寻找 v 的根if(u == v) return;father[u] = v;}public:bool validPath(int n, vector<vector<int>>& edges, int source, int destination) {if(source == destination) return true;init(n);for(int i = 0; i < edges.size(); i++){join(edges[i][0], edges[i][1]);}return isSame(source, destination);}
};

Java

class Solution {public boolean validPath(int n, int[][] edges, int source, int destination) {UF uf = new UF(n);for(int[] edge :edges) {uf.union(edge[0], edge[1]);}return uf.isConnected(source, destination);}class UF{int[] parent;public UF(int n) {parent = new int[n];for(int i = 0; i < n; i++) parent[i] = i;}private int find(int x) {if(parent[x] == x) return x;return parent[x] = find(parent[x]);}public boolean isConnected(int p, int q) {return find(p) == find(q);}public void union(int p, int q) {int pRoot = find(p), qRoot = find(q);if(pRoot != qRoot) {parent[qRoot] = pRoot;}}}
}
🚀 运行结果:

在这里插入图片描述

🕔 复杂度分析:
  • 时间复杂度 O ( n + m × α ( m ) ) O(n+m×α(m)) O(n+m×α(m)),其中 n 为图中的顶点数,m 是图中边的数目,α反阿克曼函数。并查集的初始化需要 O ( n ) O(n) O(n)的时间,然后遍历 m 条边并执行 m 次合并操作,最后对 sourcedestination 执行一次查询操作,查询与合并的单次操作时间复杂度是 O ( α ( m ) ) O(α(m)) O(α(m)),因此合并与查询的时间复杂度是 O ( m × α ( m ) ) O(m×α(m)) O(m×α(m)),总时间复杂度是 O ( n + m × α ( m ) ) O(n+m×α(m)) O(n+m×α(m))

  • 空间复杂度 O ( n ) O(n) O(n),其中 n 是图中的顶点数。并查集需要 O ( n ) O(n) O(n) 的空间。

题目来源:力扣。

放弃一件事很容易,每天能坚持一件事一定很酷,一起每日一题吧!
关注我LeetCode主页 / CSDN—力扣专栏,每日更新!

注: 如有不足,欢迎指正!

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

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

相关文章

年龄大了转嵌入式有机会吗?

年龄大了转嵌入式有机会吗&#xff1f; 首先&#xff0c;说下结论&#xff1a;年龄并不是限制转行嵌入式软件开发的因素&#xff0c;只要具备一定的编程和电子基础知识&#xff0c;认真学习和实践&#xff0c;是可以成为优秀的嵌入式软件开发工程师的。最近很多小伙伴找我&…

共铸智能未来 图为科技加入深圳市人工智能行业协会

人工智能技术的快速发展&#xff0c;为我们带来了许多革命性的创新&#xff0c;深度学习、自然语言处理、计算机 视觉等技术的突破&#xff0c;加速了人工智能的进步&#xff0c;使其能够更好地理解和处理复杂的数据和情境。这 些技术不仅在科学研究中发挥着重要作用&#xff0…

linux-如何用起来ubuntu

1 Oracle VM VirtualBox安装ubuntu20.04虚拟机 【工具】->【新建】 1.1 虚拟电脑名称和系统类型 【名称】&#xff1a;自定义名称即可 【文件夹】&#xff1a;虚拟机文件将要存储的路径 【虚拟光盘】&#xff1a;将要安装的虚拟机iso文件 1.2 自动安装 【用户名】&…

第16篇ESP32 platformio_arduino框架 wifi联网_连接WiFi热点并连接tcp server收发数据进行通讯

第1篇:Arduino与ESP32开发板的安装方法 第2篇:ESP32 helloword第一个程序示范点亮板载LED 第3篇:vscode搭建esp32 arduino开发环境 第4篇:vscodeplatformio搭建esp32 arduino开发环境 ​​​​​​第5篇:doit_esp32_devkit_v1使用pmw呼吸灯实验 第6篇:ESP32连接无源喇叭播…

通过Power Platform自定义D365 CE 业务需求 - 10.使用Power Apps和Dynamics 365的集成

集成在所有项目中都非常重要。您可以使用Microsoft本机应用程序或使用低代码、少代码概念的第三方系统集成Power Apps。在本章中,您将学习如何将本机和第三方应用程序与模型驱动的Power Apps和Dynamics 365应用程序集成。 将Outlook与Power Apps集成 以下部分概述了将Outloo…

【机器学习】详解回归(Regression)

文章目录 是什么的问题案例说明 是什么的问题 回归分析&#xff08;Regression Analysis&#xff09; 是研究自变量与因变量之间数量变化关系的一种分析方法&#xff0c;它主要是通过因变量Y与影响它的自变量 X i &#xff08; i 1 , 2 , 3 … &#xff09; X_i&#xff08;i1…

Python灰帽编程——错误异常处理和面向对象

文章目录 1. 错误和异常1.1 基本概念1.1.1 Python 异常 1.2 检测&#xff08;捕获&#xff09;异常1.2.1 try except 语句1.2.2 捕获多种异常1.2.3 捕获所有异常 1.3 处理异常1.4 特殊场景1.4.1 with 语句 2. 内网主机存活检测程序2.1 scapy 模块2.1.1 主要功能2.1.2 scapy 安装…

tp5.1 致命错误: Call to undefined method think\Cache::get()

致命错误: 致命错误: Call to undefined method think\Cache::get() 原因&#xff1a;&#xff08;引用类错误&#xff09; thinkphp5.1中有两个Cache类&#xff1a;think\Cache和think\facade\Cache。 官方文档中说使用think\Cache&#xff0c;但实际是使用think\facade\Cac…

【C++】string 之 assign、at、append函数的学习

前言 在学习string类的过程中&#xff0c;我发现了assign这个函数&#xff0c;感觉很有用&#xff0c;就来记录一下 assign函数原型&#xff1a; void assign(size_type n, const T& x T());void assign(const_iterator first, const_iterator last);assign函数有两种使…

springboot整合全局异常处理

一、项目结构 二、全局异常 &#xff08;1&#xff09;启动类 package com.mgx;import com.mgx.common.dto.Result; import com.mgx.utils.ErrorUtil; import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.spr…

TikTok的全球困境:多国整改对跨境出海的影响

TikTok&#xff08;抖音国际版&#xff09;是一款风靡全球的短视频应用程序&#xff0c;凭借其创新的内容和吸引力&#xff0c;迅速在全球范围内赢得了数以亿计的用户。 然而&#xff0c;近年来&#xff0c;TikTok在多个国家和地区面临了严峻的监管挑战和整改要求&#xff0c;…

Java21的新特性

Java语言特性系列 Java5的新特性Java6的新特性Java7的新特性Java8的新特性Java9的新特性Java10的新特性Java11的新特性Java12的新特性Java13的新特性Java14的新特性Java15的新特性Java16的新特性Java17的新特性Java18的新特性Java19的新特性Java20的新特性Java21的新特性Java22…

flash attention的CUDA编程和二维线程块实现softmax

本文参考了链接添加链接描述 flash attention介绍 flash attention的介绍可以参考论文:FlashAttention: Fast and Memory-Efficient Exact Attention with IO-Awareness,具体的数学公式参考下面这个图片:其中注意关于矩阵S有两个维度,softmax的操作维度是dim=1,用pytorc…

FireFly PowerBASIC RAD编程,调用PowerBASIC COM对象

一、序言 初步看了看PowerBASIC编程&#xff0c;很类似用VC注册窗体后调用回调函数&#xff0c;先是一个Dialog new&#xff0c;然后添加组件 Control add ......&#xff0c; 然后在处理 Windows MSG和发给组件的消息&#xff0c;这种编程方式和早期DOS 25x80屏幕上编程一样&…

1千听歌猜歌名疯狂猜歌ACCESS\EXCEL数据库

就是从今年开始&#xff0c;各类的“猜”游戏开始火爆&#xff0c;先是猜图&#xff0c;比如看图猜明星、看图猜成语、看图猜电影、看图猜电视剧、看图猜背景、看图猜游戏、看图猜影视人物、看图猜景点等。然后又开始猜音频&#xff0c;猜音频最多的是歌。甚至现在的《一站到底…

Python 数据分析学习路线

Python 数据分析学习路线 第一阶段&#xff1a;Python语言基础第二阶段&#xff1a;数据采集和持久化第三阶段&#xff1a;数据分析第四阶段&#xff1a;数据挖掘与机器学习书籍介绍参与方式 第一阶段&#xff1a;Python语言基础 在学习数据分析之前&#xff0c;首先需要掌握P…

探究Nginx应用场景

1 静态资源 Nginx是一个流行的Web服务器和反向代理服务器&#xff0c;它可以用于托管静态资源。下面是一个简单的案例&#xff0c;展示了如何使用Nginx来提供静态资源。 假设你有一个名为example.com的域名&#xff0c;并且你希望使用Nginx来托管位于/var/www/html目录下的静…

知名IT网站博客园陷入绝境

我是卢松松&#xff0c;点点上面的头像&#xff0c;欢迎关注我哦&#xff01; 博客园陷入生死存亡的绝境。 5月份知名IT开发者网站发布文章称“博客园网站遇到困难了&#xff1a;寻求捐助”&#xff0c;并开通了捐助渠道。4个月过去了&#xff0c;好像效果并不明显&#xff…

毕业设计|基于stm32单片机的app视频遥控抽水灭火小车设计

基于stm32单片机的app视频遥控抽水灭火水泵小车设计 1、项目简介1.1 系统构成1.2 系统功能 2、部分电路设计2.1 L298N电机驱动电路设计2.2 继电器控制电路设计 3、部分代码展示3.1 小车控制代码3.1 水泵控制代码 4 演示视频及代码资料获取 1、项目简介 视频简介中包含资料http…

iOS 17中的Safari配置文件改变了游戏规则,那么如何设置呢

Safari在iOS 17中最大的升级是浏览配置文件——能够在一个应用程序中创建单独的选项卡和书签组。这些也可以跟随你的iPad和Mac&#xff0c;但在本指南中&#xff0c;我们将向你展示如何使用运行iOS 17的iPhone。 你可能有点困惑&#xff0c;为什么Safari中没有明显的位置可以添…