1971e. 寻找图中是否存在路径
题目链接
代码随想录文章讲解链接
方法一:并查集
用时:10m6s
思路
- 时间复杂度: O ( n log n ) O(n\log{n}) O(nlogn)
- 空间复杂度: O ( n ) O(n) O(n)
C++代码
class Solution {
private:vector<int> father;void init(int n) {// 初始化并查集,每个节点的根都是自己father = vector<int>(n);for (int i = 0; i < n; ++i) father[i] = i;}int find(int a) {// 查找根,并且压缩路径return a == father[a] ? a : father[a] = find(father[a]);}bool isSame(int a, int b) {// 判断两个节点是否在同一个集合中,即两个节点是否是同一个根return find(a) == find(b);}void join(int a, int b) {// 将a节点和b节点合并到同一个集合中,即让b的根指向a的根a = find(a);b = find(b);if (a != b) father[b] = a;}public:bool validPath(int n, vector<vector<int>>& edges, int source, int destination) {init(n); // 初始化并查集for (int i = 0; i < edges.size(); ++i) join(edges[i][0], edges[i][1]); // 根据边更新并查集return isSame(source, destination); // 判断两个节点是否在同一个集合}
};
方法二:BFS
用时:11m20s
思路
- 时间复杂度: O ( n + m ) O(n+m) O(n+m)。
- 空间复杂度: O ( n + m ) O(n+m) O(n+m)。
C++代码
class Solution {
public:bool validPath(int n, vector<vector<int>>& edges, int source, int destination) {// 构建邻接矩阵vector<vector<int>> adj(n);vector<bool> visited(n, false);for (int i = 0; i < edges.size(); ++i) {int node1 = edges[i][0];int node2 = edges[i][1];adj[node1].emplace_back(node2);adj[node2].emplace_back(node1);}// BFSqueue<int> que;que.push(source);visited[source] = true;while (!que.empty()) {int cur = que.front();if (cur == destination) return true;que.pop();for (int i = 0; i < adj[cur].size(); ++i) {if (!visited[adj[cur][i]]) {visited[adj[cur][i]] = true;que.push(adj[cur][i]);}}}return false;}
};
方法三:DFS
用时:27m50s
思路
先构建邻接表,记录每个节点可以通往的节点;然后从source节点开始DFS,dfs递归函数的返回值不是void,是bool,当dfs过程中到达了destination,则返回true,注意不能直接递归内部不能直接返回dfs(…),因为即使一条dfs路径无法到达destination,也可能有其他路径。
- 时间复杂度: O ( n + m ) O(n+m) O(n+m)。
- 空间复杂度: O ( n + m ) O(n+m) O(n+m)。
C++代码
class Solution {
private:bool dfs(vector<vector<int>>& adj, vector<bool>& visited, int source, int destination) {if (source == destination) return true;visited[source] = true;for (int i = 0; i < adj[source].size(); ++i) {if (!visited[adj[source][i]] && dfs(adj, visited, adj[source][i], destination)) return true;}return false;}public:bool validPath(int n, vector<vector<int>>& edges, int source, int destination) {vector<vector<int>> adj(n);vector<bool> visited(n, false);for (int i = 0; i < edges.size(); ++i) {int node1 = edges[i][0];int node2 = edges[i][1];adj[node1].emplace_back(node2);adj[node2].emplace_back(node1);}return dfs(adj, visited, source, destination);}
};
看完讲解的思考
无。
代码实现遇到的问题
无。
684m. 冗余连接
题目链接
代码随想录文章讲解链接
方法一:并查集
用时:25m21s
思路
- 时间复杂度: O ( n log n ) O(n\log{n}) O(nlogn)。
- 空间复杂度: O ( n ) O(n) O(n)。
C++代码
class Solution {
private:vector<int> father;void init(int n) {father = vector<int>(n + 1);for (int i = 1; i < n + 1; ++i) father[i] = i;}int find(int a) {return a == father[a] ? a : father[a] = find(father[a]);}bool isSame(int a, int b) {return find(a) == find(b);}void join(int a, int b) {a = find(a);b = find(b);if (a != b) father[b] = a;}public:vector<int> findRedundantConnection(vector<vector<int>>& edges) {init(edges.size());for (auto& edge : edges) {if (isSame(edge[0], edge[1])) return edge;join(edge[0], edge[1]);}return {0, 0};}
};
看完讲解的思考
无。
代码实现遇到的问题
无。
最后的碎碎念
一刷代码随想录完结撒花~!!!
虽然其实最后图论部分偷懒了,hard题都没做,主要是因为最近要开始找实习了,时间比较赶,hard题就先不做了,我找个日常实习而已,应该不会出图论的hard题目…吧…
所以图论只是把基础内容过了一下,接下来还是先赶紧去捡起前面的题型,复习一下。