题目来源
题目描述
class Solution {
public:
bool validTree(int n, vector<vector<int>>& edges) {
}
};
题目分析
思路
- 树是一种特殊的无向图,是有n个顶点,n-1条边的图;而且是连通图。
- 条件1,n个顶点,n-1条边,很好判断
- 条件2,连通图,如何判断呢?
- 什么是连通图?就是图中任意两点都是连通的。
- 如何判断任意两点都是连通的呢?
- 可以用并查集,最后判断并查集联通个数是否为1
- 可以遍历图,然后计数,遍历完成之后,看最终的计数数量是否等于n,或者看联通分离是否是1
DFS
class Solution {
std::vector<bool>visited;
int count = 0;
void dfs(std::vector<std::vector<int>> &graph, int point){
if(visited[point]){
return;
}
visited[point] = true;
count++;;
for(int neighbor : graph[point]){
dfs(graph, neighbor );
}
}
public:
bool validTree(int n, vector<vector<int>>& edges) {
if(edges.empty() || edges.size() != n - 1){
return false;
}
std::vector<std::vector<int>> graph(n, std::vector<int>(n));
for(auto e : edges){
graph[e[0]].push_back(e[1]);
graph[e[1]].push_back(e[0]);
}
visited.resize(n);
return count == n;
}
};
并查集
使用并查集,当一条边的两个节点已经处于联通状态时,新加的边就肯定构成了环。
- 对于添加的这条边,如果该边的两个节点本来就在同一连通分量里,那么添加这条边会产生环;
- 反之,如果该边的两个节点不在同一连通分量里,则添加这条边不会产生环。
class Solution {
public:
bool validTree(int n, vector<vector<int>>& edges) {
UF uf(n);
// 遍历所有边,将组成边的两个节点进行连接
for(int i=0;i<edges.size();++i){
int p=edges[i][0];
int q=edges[i][1];
// 若两个节点已经在同一连通分量中,会产生环
if(uf.connected(p,q)){
return false;
}
// 这条边不会产生环,可以是树的一部分
uf.Union(p,q);
}
// 要保证最后只形成了一棵树,即只有一个连通分量
return uf.count==1;
}
class UF{
public:
UF(int n){
count=n;
for(int i=0;i<n;++i){
parent.push_back(i);
size.push_back(1);
}
}
void Union(int p,int q){
int rootp=find(p);
int rootq=find(q);
if(rootp==rootq){
return;
}
if(size[rootp]>size[rootq]){
size[rootq]+=size[rootp];
parent[rootp]=rootq;
}else{
size[rootq]+=size[rootp];
parent[rootq]=rootp;
}
count--;
}
int find(int x){
while(x!=parent[x]){
parent[x]=parent[parent[x]];
x=parent[x];
}
return x;
}
bool connected(int p,int q){
int rootp=find(p);
int rootq=find(q);
return rootp==rootq;
}
int count;
vector<int> parent;
vector<int> size;
};
};
类似题目
题目 | 思路 |
---|---|
leetcode:200. 岛屿数量 Number of Islands | dfs、并查集 |
leetcode:261. 以图判树 Graph Valid Tree | |
leetcode:990. 等式方程的可满足性 Satisfiability of Equality Equations | |
leetcode:685. 冗余连接 II Redundant Connection II |