题目描述
节点间通路。给定有向图,设计一个算法,找出两个节点之间是否存在一条路径。
示例1:
- 输入:n = 3, graph = [[0, 1], [0, 2], [1, 2], [1, 2]], start = 0, target = 2
输出:true
示例2:
- 输入:n = 5, graph = [[0, 1], [0, 2], [0, 4], [0, 4], [0, 1], [1, 3], [1, 4], [1, 3], [2, 3], [3, 4]], start = 0, target = 4
输出 true
提示:
节点数量n在[0, 1e5]范围内。
节点编号大于等于 0 小于 n。
图中可能存在自环和平行边。
解题思路与代码
做这道题之前,需要你对DFS
(深度优先算法),BFS
(广度优先算法),邻接表
(一种存储结构),有向图
(图的一种,是一种数据结构)有着一些基本的了解。否则你光干瞪着眼看题,是看不出什么结果的。
首先从头来解释一下这道题,首先题目给的graph是一个二维数组,其中的每一个元素都是一个存储着两个元素的vector。vector中的每一个不重复的数字,都代表着一个节点。每一个vector中都有两个元素,将这两个元素想象成两个节点,那就是第一个节点指向第二个节点。
将graph中的每一个节点的指向都画出来的话,你就可以得到一张有向图。
邻接表 + DFS
首先,我们需要题目给的有向图去存储到邻接表之中去。那么存储图的邻接表的代码长这样:
vector<vector<int>> vec(n);
其中n就是节点的个数啦。可以想象,邻接表就是将图中的每一个节点都当做一个链表,节点本身就是链表的头节点。后面连着几个节点,我们就将这些节点添加到头节点对应的vector中去。
那这道题解题的第一步就是,将图按照邻接表的形式存储在vector中。
第二步就是深度优先遍历,深度优先遍历的本质上是递归
。因为我们都知道了,二维vector中的每一个vector都代表着一条路线。我们只需要将每条路线都一一走到头,就能判断出来,有没有题目中给出的start -> target的这条路线了。
具体的代码如下:
class Solution {
public:// 邻接表+DFS
bool findWhetherExistsPath(int n, vector<vector<int>>& graph, int start, int target) {
// 初始化邻接表为容量为n的二维向量, 存储有向边
vector<vector<int>> vec(n); // 外面的这个vector有n个元素,都是vector
// 将图中的有向边存入邻接表Vec
for (const auto& g : graph) { //g是一个vector,里面存放了两个元素。
vec[g[0]].push_back(g[1]);//下标为g[0]的vector中添加了一个数字,这个数字是g[1]
}
// 调用dfs函数,执行深度优先搜索
return dfs(vec, start, target);
}
bool dfs( vector<vector<int>>& vec, int start, int target) {
// 如果起点和终点相同,则存在连通路径,返回true
if (start == target) {
return true;
}
// 依次遍历从起点可直接到达的节点v,递归地调用函数,并以v为新起点进行下一轮搜索
for (const auto& v : vec[start]) { //这个vec[start]本身代指的是一个一维数组。
if(dfs( vec, v, target)) {
return true;
}
}
// 若所有路径都走不到终点,则不存在连通路径,返回false
return false;
}
};
复杂度分析
时间复杂度:
对于邻接表的创建,需要遍历一次整个图中所有的边,其时间复杂度为 O(E),其中 E 表示边数。
对于 DFS 遍历,每一个点最多只会被访问一次,在最坏情况下,需要访问图中所有的点,因此其时间复杂度为 O(n),其中 n 表示点数。
综上所述,该算法的时间复杂度为 O(E + n)。
空间复杂度:
邻接表使用了一个二维向量来存储边信息,其大小为 O(E),其中 E 表示边数。由于 E 不超过 n^2 的级别,因此该向量的空间需求不会超过 O(n^2)。
在 DFS 的递归调用过程中,根据深度可能会生成 O(n) 个递归层级。而每一层递归函数在栈中占用的空间是常数级别的 O(1),因此 DFS 所需要的空间是 O(n) 级别的。
综上所述,该算法的空间复杂度为 O(n^2+n),即 O(n^2) 级别。
因此,总的来说,该算法的时间复杂度为 O(E+n),空间复杂度为 O(n^2)。