[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), write a function to check whether these edges make up a valid tree.
For example:
Given n = 5
and edges = [[0, 1], [0, 2], [0, 3], [1, 4]]
, return true
.
Given n = 5
and edges = [[0, 1], [1, 2], [2, 3], [1, 3], [1, 4]]
, return false
.
Hint:
- Given
n = 5
andedges = [[0, 1], [1, 2], [3, 4]]
, what should your return? Is this case a valid tree? - According to the definition of tree on Wikipedia: “a tree is an undirected graph in which any two vertices are connected by exactly one path. In other words, any connected graph without simple cycles is a tree.”
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
.
给一个无向图,判断其是否为一棵树。如果是树的话,所有的节点必须是连接的,也就是说必须是连通图,而且不能有环,所以就变成了验证是否是连通图和是否含有环。
解法1: DFS
解法2: BFS
解法3: Union Find
Java: DFS
public boolean validTree(int n, int[][] edges) {
HashMap<Integer, ArrayList<Integer>> map = new HashMap<Integer, ArrayList<Integer>>();
for(int i=0; i<n; i++){
ArrayList<Integer> list = new ArrayList<Integer>();
map.put(i, list);
} for(int[] edge: edges){
map.get(edge[0]).add(edge[1]);
map.get(edge[1]).add(edge[0]);
} boolean[] visited = new boolean[n]; if(!helper(0, -1, map, visited))
return false; for(boolean b: visited){
if(!b)
return false;
} return true;
} public boolean helper(int curr, int parent, HashMap<Integer, ArrayList<Integer>> map, boolean[] visited){
if(visited[curr])
return false; visited[curr] = true; for(int i: map.get(curr)){
if(i!=parent && !helper(i, curr, map, visited)){
return false;
}
} return true;
}
Java: BFS
public boolean validTree(int n, int[][] edges) {
HashMap<Integer, ArrayList<Integer>> map = new HashMap<Integer, ArrayList<Integer>>();
for(int i=0; i<n; i++){
ArrayList<Integer> list = new ArrayList<Integer>();
map.put(i, list);
} for(int[] edge: edges){
map.get(edge[0]).add(edge[1]);
map.get(edge[1]).add(edge[0]);
} boolean[] visited = new boolean[n]; LinkedList<Integer> queue = new LinkedList<Integer>();
queue.offer(0);
while(!queue.isEmpty()){
int top = queue.poll();
if(visited[top])
return false; visited[top]=true; for(int i: map.get(top)){
if(!visited[i])
queue.offer(i);
}
} for(boolean b: visited){
if(!b)
return false;
} return true;
Java:BFS
public class Solution {
/**
* @param n an integer
* @param edges a list of undirected edges
* @return true if it's a valid tree, or false
*/
public boolean validTree(int n, int[][] edges) {
if (n == 0) {
return false;
} if (edges.length != n - 1) {
return false;
} Map<Integer, Set<Integer>> graph = initializeGraph(n, edges); // bfs
Queue<Integer> queue = new LinkedList<>();
Set<Integer> hash = new HashSet<>(); queue.offer(0);
hash.add(0);
while (!queue.isEmpty()) {
int node = queue.poll();
for (Integer neighbor : graph.get(node)) {
if (hash.contains(neighbor)) {
continue;
}
hash.add(neighbor);
queue.offer(neighbor);
}
} return (hash.size() == n);
} private Map<Integer, Set<Integer>> initializeGraph(int n, int[][] edges) {
Map<Integer, Set<Integer>> graph = new HashMap<>();
for (int i = 0; i < n; i++) {
graph.put(i, new HashSet<Integer>());
} for (int i = 0; i < edges.length; i++) {
int u = edges[i][0];
int v = edges[i][1];
graph.get(u).add(v);
graph.get(v).add(u);
} return graph;
}
}
Java: Union Find
public class Solution {
class UnionFind{
HashMap<Integer, Integer> father = new HashMap<Integer, Integer>();
UnionFind(int n){
for(int i = 0 ; i < n; i++) {
father.put(i, i);
}
}
int compressed_find(int x){
int parent = father.get(x);
while(parent!=father.get(parent)) {
parent = father.get(parent);
}
int temp = -1;
int fa = father.get(x);
while(fa!=father.get(fa)) {
temp = father.get(fa);
father.put(fa, parent) ;
fa = temp;
}
return parent; } void union(int x, int y){
int fa_x = compressed_find(x);
int fa_y = compressed_find(y);
if(fa_x != fa_y)
father.put(fa_x, fa_y);
}
}
/**
* @param n an integer
* @param edges a list of undirected edges
* @return true if it's a valid tree, or false
*/
public boolean validTree(int n, int[][] edges) {
// tree should have n nodes with n-1 edges
if (n - 1 != edges.length) {
return false;
} UnionFind uf = new UnionFind(n); for (int i = 0; i < edges.length; i++) {
if (uf.compressed_find(edges[i][0]) == uf.compressed_find(edges[i][1])) {
return false;
}
uf.union(edges[i][0], edges[i][1]);
}
return true;
}
}
Python: DFS
class Solution(object):
def validTree(self, n, edges):
lookup = collections.defaultdict(list)
for edge in edges:
lookup[edge[0]].append(edge[1])
lookup[edge[1]].append(edge[0])
visited = [False] * n if not self.helper(0, -1, lookup, visited):
return False for v in visited:
if not v:
return False return True def helper(self, curr, parent, lookup, visited):
print curr, visited
if visited[curr]:
return False
visited[curr] = True
for i in lookup[curr]:
if (i != parent and not self.helper(i, curr, lookup, visited)):
return False return True if __name__ == '__main__':
print Solution().validTree(5, [[0, 1], [0, 2], [0, 3], [1, 4]])
print Solution().validTree(5, [[0, 1], [1, 2], [2, 3], [1, 3], [1, 4]])
Python: BFS, Time: O(|V| + |E|), Space: O(|V| + |E|)
class Solution(object):
# @param {integer} n
# @param {integer[][]} edges
# @return {boolean}
def validTree(self, n, edges):
if len(edges) != n - 1: # Check number of edges.
return False # init node's neighbors in dict
neighbors = collections.defaultdict(list)
for u, v in edges:
neighbors[u].append(v)
neighbors[v].append(u) # BFS to check whether the graph is valid tree.
visited = {}
q = collections.deque([0])
while q:
curr = q.popleft()
visited[curr] = True
for node in neighbors[curr]:
if node not in visited:
visited[node] = True
q.append(node) return len(visited) == n
Python: Union Find
class Solution:
# @param {int} n an integer
# @param {int[][]} edges a list of undirected edges
# @return {boolean} true if it's a valid tree, or false
def validTree(self, n, edges):
# Write your code here
root = [i for i in range(n)]
for i in edges:
root1 = self.find(root, i[0])
root2 = self.find(root, i[1])
if root1 == root2:
return False
else:
root[root1] = root2
return len(edges) == n - 1 def find(self, root, e):
if root[e] == e:
return e
else:
root[e] = self.find(root, root[e])
return root[e]
C++: 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, 0, -1)) 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;
}
};
C++: 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{{0}};
queue<int> q{{0}};
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;
}
};
C++: Union Find
class Solution {
public:
bool validTree(int n, vector<pair<int, int>>& edges) {
vector<int> roots(n, -1);
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 - 1;
}
int find(vector<int> &roots, int i) {
while (roots[i] != -1) i = roots[i];
return i;
}
};
类似题目:
[LeetCode] 200. Number of Islands 岛屿的数量
[LeetCode] 305. Number of Islands II 岛屿的数量之二
[LeetCode] 323. Number of Connected Components in an Undirected Graph 无向图中的连通区域的个数
All LeetCode Questions List 题目汇总
[LeetCode] 261. Graph Valid Tree 图是否是树的更多相关文章
- [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 ...
- [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 ...
- [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), ...
- 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 nod ...
- [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), ...
- LeetCode Graph Valid Tree
原题链接在这里:https://leetcode.com/problems/graph-valid-tree/ 题目: Given n nodes labeled from 0 to n - 1 an ...
- 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), ...
- 图是否是树 · Graph Valid Tree
[抄题]: 给出 n 个节点,标号分别从 0 到 n - 1 并且给出一个 无向边的列表 (给出每条边的两个顶点), 写一个函数去判断这张`无向`图是否是一棵树. 给出n = 5 并且 edges = ...
随机推荐
- 【Audiophobia UVA - 10048 】【Floyd算法】
题目大意:从a城市到b城市的路径中,尽可能让一路上的最大噪音最小. 题目思路:设d [ i ][ j ]表示 i 到 j 的最大噪音的最小值. 那么d [ i ][ j ] = min( d[ i ] ...
- 使用Xpath+多进程爬取诗词名句网的史书典籍类所有文章。update~
上次写了爬取这个网站的程序,有一些地方不完善,而且爬取速度较慢,今天完善一下并开启多进程爬取,速度就像坐火箭.. # 需要的库 from lxml import etree import reques ...
- 路由器安全——破解wifi密码,同时中间人攻击
聊聊安全那些事儿 篇一:Wi-Fi安全浅析 2016-04-25 13:18:16 141点赞 712收藏 63评论 前言 近期,Wi-Fi相关的安全话题充斥着电视新闻的大屏幕,先是曝出了路由器劫持的 ...
- Kotlin协程重要概念详解【纯理论】
在之前对Kotlin的反射进行了详细的学习,接下来进入一个全新的篇章,就是关于Koltin的协程[coroutine],在正式撸码之前先对它有一个全面理论化的了解: 协程的定义: 协和通过将复杂性放入 ...
- jdbc.DataSourceProperties$DataSourceBeanCreationException: Failed to determine a suitable driver class
java.lang.IllegalStateException: Failed to load ApplicationContext at org.springframework.test.conte ...
- [Ignatius and the Princess III] 整数的无序拆分(DP + 生成函数)
整数的有序拆分就是隔板法,无序拆分则有两种处理方法 DP递推 我们假设P(n,m)P(n,m)P(n,m)是正整数nnn无序拆分为mmm个正整数的方案数 对于某一种拆分,不妨将拆分出来的mmm个数从小 ...
- 09-Flutter移动电商实战-移动商城数据请求实战
1.URL接口管理文件建立 第一步需要在建立一个URL的管理文件,因为课程的接口会一直进行变化,所以单独拿出来会非常方便变化接口.当然工作中的URL管理也是需要这样配置的,以为我们会不断的切换好几个服 ...
- 002_Visual Studio (gnuplot)显示数组波形
视频教程:https://v.qq.com/x/page/e3039v4j6zs.html 资料下载:https://download.csdn.net/download/xiaoguoge11/12 ...
- 利用Python进行数据分析【第二版】【高清中文版英文版源代码】
如果被河蟹请回复我更新链接 这是我花钱弄的,免费分享给大家.没有密码,直接可以观看! 希望大家不要拿去后再做收费分享 如果好用,请给个赞好嘛~~~ 1.中文pdf 链接:https:/ ...
- Android入门教程(一)
Android是什么? Android是基于Linux开发性内核的操作系统,该平台由操作系统,中间件,用户界面和应用软件组成.Android的基本信息:软件类型,APK,发行商:Google,最早版本 ...