题目链接
代码随想录文章讲解链接
用时:10m6s
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); // 判断两个节点是否在同一个集合
}
};
用时:11m20s
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);
}
// BFS
queue<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;
}
};
用时:27m50s
先构建邻接表,记录每个节点可以通往的节点;然后从source节点开始DFS,dfs递归函数的返回值不是void,是bool,当dfs过程中到达了destination,则返回true,注意不能直接递归内部不能直接返回dfs(…),因为即使一条dfs路径无法到达destination,也可能有其他路径。
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);
}
};
无。
无。
题目链接
代码随想录文章讲解链接
用时:25m21s
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题目…吧…
所以图论只是把基础内容过了一下,接下来还是先赶紧去捡起前面的题型,复习一下。