[LeetCode] Graph Valid Tree 图验证树
Given n nodes labeled from 0 to n-1 and a list of undirected edges (each edge is a pair of nodes), write a function to check whether these edges make up a valid tree.
Example 1:
Input:n = 5, andedges = [[0,1], [0,2], [0,3], [1,4]]
Output: true
Example 2:
Input:n = 5,andedges = [[0,1], [1,2], [2,3], [1,3], [1,4]]
Output: false
Note: you can assume that no duplicate edges will appear in edges. Since all edges are undirected, [0,1] is the same as [1,0] and thus will not appear together in edges.
这道题给了一个无向图,让我们来判断其是否为一棵树,如果是树的话,所有的节点必须是连接的,也就是说必须是连通图,而且不能有环,所以焦点就变成了验证是否是连通图和是否含有环。首先用 DFS 来做,根据 pair 来建立一个图的结构,用邻接链表来表示,还需要一个一位数组v来记录某个结点是否被访问过,然后用 DFS 来搜索结点0,遍历的思想是,当 DFS 到某个结点,先看当前结点是否被访问过,如果已经被访问过,说明环存在,直接返回 false,如果未被访问过,现在将其状态标记为已访问过,然后到邻接链表里去找跟其相邻的结点继续递归遍历,注意还需要一个变量 pre 来记录上一个结点,以免回到上一个结点,这样遍历结束后,就把和结点0相邻的节点都标记为 true,然后再看v里面是否还有没被访问过的结点,如果有,则说明图不是完全连通的,返回 false,反之返回 true,参见代码如下:
解法一:
// DFS
class Solution {
public:
bool validTree(int n, vector<pair<int, int>>& edges) {
vector<vector<int>> g(n, vector<int>());
vector<bool> v(n, false);
for (auto a : edges) {
g[a.first].push_back(a.second);
g[a.second].push_back(a.first);
}
if (!dfs(g, v, , -)) return false;
for (auto a : v) {
if (!a) return false;
}
return true;
}
bool dfs(vector<vector<int>> &g, vector<bool> &v, int cur, int pre) {
if (v[cur]) return false;
v[cur] = true;
for (auto a : g[cur]) {
if (a != pre) {
if (!dfs(g, v, a, cur)) return false;
}
}
return true;
}
};
下面来看 BFS 的解法,思路很相近,需要用 queue 来辅助遍历,这里没有用一维向量来标记节点是否访问过,而是用了一个 HashSet,如果遍历到一个节点,在 HashSet 中没有,则加入 HashSet,如果已经存在,则返回false,还有就是在遍历邻接链表的时候,遍历完成后需要将结点删掉,参见代码如下:
解法二:
// BFS
class Solution {
public:
bool validTree(int n, vector<pair<int, int>>& edges) {
vector<unordered_set<int>> g(n, unordered_set<int>());
unordered_set<int> s{{}};
queue<int> q{{}};
for (auto a : edges) {
g[a.first].insert(a.second);
g[a.second].insert(a.first);
}
while (!q.empty()) {
int t = q.front(); q.pop();
for (auto a : g[t]) {
if (s.count(a)) return false;
s.insert(a);
q.push(a);
g[a].erase(t);
}
}
return s.size() == n;
}
};
我们再来看 Union Find 的方法,这种方法对于解决连通图的问题很有效,思想是遍历节点,如果两个节点相连,将其 roots 值连上,这样可以找到环,初始化 roots 数组为 -1,然后对于一个 pair 的两个节点分别调用 find 函数,得到的值如果相同的话,则说明环存在,返回 false,不同的话,将其 roots 值 union 上,参见代码如下:
解法三:
// Union Find
class Solution {
public:
bool validTree(int n, vector<pair<int, int>>& edges) {
vector<int> roots(n, -);
for (auto a : edges) {
int x = find(roots, a.first), y = find(roots, a.second);
if (x == y) return false;
roots[x] = y;
}
return edges.size() == n - ;
}
int find(vector<int> &roots, int i) {
while (roots[i] != -) i = roots[i];
return i;
}
};
Github 同步地址:
https://github.com/grandyang/leetcode/issues/261
类似题目:
Number of Connected Components in an Undirected Graph
参考资料:
https://leetcode.com/problems/graph-valid-tree/
https://leetcode.com/problems/graph-valid-tree/discuss/69018/AC-Java-Union-Find-solution
LeetCode All in One 题目讲解汇总(持续更新中...)
[LeetCode] Graph Valid Tree 图验证树的更多相关文章
- [LeetCode] 261. Graph Valid Tree 图是否是树
Given n nodes labeled from 0 to n - 1 and a list of undirected edges (each edge is a pair of nodes), ...
- Leetcode: Graph Valid Tree && Summary: Detect cycle in undirected graph
Given n nodes labeled from 0 to n - 1 and a list of undirected edges (each edge is a pair of nodes), ...
- LeetCode Graph Valid Tree
原题链接在这里:https://leetcode.com/problems/graph-valid-tree/ 题目: Given n nodes labeled from 0 to n - 1 an ...
- [Locked] Graph Valid Tree
Graph Valid Tree Given n nodes labeled from 0 to n - 1 and a list of undirected edges (each edge is ...
- [Swift]LeetCode261.图验证树 $ Graph Valid Tree
Given n nodes labeled from 0 to n - 1 and a list of undirected edges (each edge is a pair of nodes), ...
- 图是否是树 · Graph Valid Tree
[抄题]: 给出 n 个节点,标号分别从 0 到 n - 1 并且给出一个 无向边的列表 (给出每条边的两个顶点), 写一个函数去判断这张`无向`图是否是一棵树. 给出n = 5 并且 edges = ...
- [LeetCode#261] Graph Valid Tree
Problem: Given n nodes labeled from 0 to n - 1 and a list of undirected edges (each edge is a pair o ...
- Graph Valid Tree -- LeetCode
Given n nodes labeled from 0 to n - 1 and a list of undirected edges (each edge is a pair of nodes), ...
- [LeetCode] 261. Graph Valid Tree _ Medium tag: BFS
Given n nodes labeled from 0 to n-1 and a list of undirected edges (each edge is a pair of nodes), w ...
随机推荐
- Properties操作指南
一.简介: Properties是java中用的比较多的一个类,表示一个持久的属性集.继承于Hashtable,Properties可从流中加载,也可保存在流中.属性列表中每个键极其对应值共同组成一个 ...
- 【分布式】Zookeeper系统模型
一.前言 前面已经讲解了Zookeeper的一些应用场景,但是并没有深入到Zookeeper内部进行分析,本篇将讲解其系统模型. 二.系统模型 2.1 数据模型 Zookeeper的数据节点称为ZNo ...
- Windows下Git多账号配置,同一电脑多个ssh-key的管理
这一篇文章是对上一篇文章<Git-TortoiseGit完整配置流程>的拓展,所以需要对上一篇文章有所了解,当然直接往下看也可以,其中也有一些提到一些基础的操作. <Git-Tort ...
- JavaScript学习(一) —— 环境搭建与JavaScript初探
1.开发环境搭建 本系列教程的开发工具,我们采用HBuilder. 可以去网上下载最新的版本,然后解压一下就能直接用了.学习JavaScript,环境搭建是非常简单的,或者说,只要你有一个浏览器,一个 ...
- 基于WebGL 的3D呈现A* Search Algorithm
http://www.hightopo.com/demo/astar/astar.html 最近搞个游戏遇到最短路径的常规游戏问题,一时起兴基于HT for Web写了个A*算法的WebGL 3D呈现 ...
- C# WCF服务端搭建和客户端调用
1) 打开Visual Studio 2012,在菜单上点击文件->新建->项目->WCF服务应用程序.在弹出界面的"名称"对应的文本框中输入"WcfS ...
- Qt安装配置
Qt Creator: 下载: Qt 5.5.1 for Windows 32-bit(MinGW 4.9.2, 1.0 GB):http://download.qt.io/official_rele ...
- wpf 列表、菜单 收起与展开,通过Grid DoubleAnimation或者Expander实现
菜单收缩有很多种方法具体如何实现还是看个人想法: 第一种通过后台控制收起与展开: 效果图: 代码 : <Grid> <Grid.ColumnDefinitions> <C ...
- PHP函数基础知识.png
- Lind.DDD.SSO单点登陆组件的使用(原创)
回到目录 一般sso的说明 在Lind.DDD框架里,有对单点登陆的集成,原理就是各个网站去sso网站统一登陆授权,之后在sso网站将登陆的token进行存储,存储方式随你(cache,redis,m ...