[LeetCode] Minimum Height Trees 最小高度树
For a undirected graph with tree characteristics, we can choose any node as the root. The result graph is then a rooted tree. Among all possible rooted trees, those with minimum height are called minimum height trees (MHTs). Given such a graph, write a function to find all the MHTs and return a list of their root labels.
Format
The graph contains n nodes which are labeled from 0 to n - 1. You will be given the number n and a list of undirected edges (each edge is a pair of labels).
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.
Example 1:
Given n = 4, edges = [[1, 0], [1, 2], [1, 3]]
0
|
1
/ \
2 3
return [1]
Example 2:
Given n = 6, edges = [[0, 3], [1, 3], [2, 3], [4, 3], [5, 4]]
0 1 2
\ | /
3
|
4
|
5
return [3, 4]
Hint:
- How many MHTs can a graph have at most?
Note:
(1) 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.”
(2) The height of a rooted tree is the number of edges on the longest downward path between the root and a leaf.
Credits:
Special thanks to @peisi for adding this problem and creating all test cases.
Update (2015-11-25):
The function signature had been updated to return List<Integer> instead of integer[]. Please click the reload button above the code editor to reload the newest default code definition.
这道题虽然是树的题目,但是跟其最接近的题目是Course Schedule 课程清单和Course Schedule II 课程清单之二。由于LeetCode中的树的题目主要都是针对于二叉树的,而这道题虽说是树但其实本质是想考察图的知识,这道题刚开始在拿到的时候,我最先想到的解法是遍历的点,以每个点都当做根节点,算出高度,然后找出最小的,但是一时半会又写不出程序来,于是上网看看大家的解法,发现大家推崇的方法是一个类似剥洋葱的方法,就是一层一层的褪去叶节点,最后剩下的一个或两个节点就是我们要求的最小高度树的根节点,这种思路非常的巧妙,而且实现起来也不难,跟之前那到课程清单的题一样,我们需要建立一个图g,是一个二维数组,其中g[i]是一个一维数组,保存了i节点可以到达的所有节点。我们开始将所有只有一个连接边的节点(叶节点)都存入到一个队列queue中,然后我们遍历每一个叶节点,通过图来找到和其相连的节点,并且在其相连节点的集合中将该叶节点删去,如果删完后此节点也也变成一个叶节点了,加入队列中,再下一轮删除。那么我们删到什么时候呢,当节点数小于等于2时候停止,此时剩下的一个或两个节点就是我们要求的最小高度树的根节点啦,参见代码如下:
C++ 解法一:
class Solution {
public:
vector<int> findMinHeightTrees(int n, vector<pair<int, int> >& edges) {
if (n == ) return {};
vector<int> res;
vector<unordered_set<int>> adj(n);
queue<int> q;
for (auto edge : edges) {
adj[edge.first].insert(edge.second);
adj[edge.second].insert(edge.first);
}
for (int i = ; i < n; ++i) {
if (adj[i].size() == ) q.push(i);
}
while (n > ) {
int size = q.size();
n -= size;
for (int i = ; i < size; ++i) {
int t = q.front(); q.pop();
for (auto a : adj[t]) {
adj[a].erase(t);
if (adj[a].size() == ) q.push(a);
}
}
}
while (!q.empty()) {
res.push_back(q.front()); q.pop();
}
return res;
}
};
Java 解法一:
public class Solution {
public List<Integer> findMinHeightTrees(int n, int[][] edges) {
if (n == 1) return Collections.singletonList(0);
List<Integer> leaves = new ArrayList<>();
List<Set<Integer>> adj = new ArrayList<>(n);
for (int i = 0; i < n; ++i) adj.add(new HashSet<>());
for (int[] edge : edges) {
adj.get(edge[0]).add(edge[1]);
adj.get(edge[1]).add(edge[0]);
}
for (int i = 0; i < n; ++i) {
if (adj.get(i).size() == 1) leaves.add(i);
}
while (n > 2) {
n -= leaves.size();
List<Integer> newLeaves = new ArrayList<>();
for (int i : leaves) {
int t = adj.get(i).iterator().next();
adj.get(t).remove(i);
if (adj.get(t).size() == 1) newLeaves.add(t);
}
leaves = newLeaves;
}
return leaves;
}
}
此题还有递归的解法(未完待续...)
类似题目:
参考资料:
https://discuss.leetcode.com/topic/30572/share-some-thoughts/2
https://discuss.leetcode.com/topic/67543/java-o-n-solution-with-explanation-dfs-twice-beat-95
LeetCode All in One 题目讲解汇总(持续更新中...)
[LeetCode] Minimum Height Trees 最小高度树的更多相关文章
- [LeetCode] 310. Minimum Height Trees 最小高度树
For a undirected graph with tree characteristics, we can choose any node as the root. The result gra ...
- LeetCode Minimum Height Trees
原题链接在这里:https://leetcode.com/problems/minimum-height-trees/ 题目: For a undirected graph with tree cha ...
- [Swift]LeetCode310. 最小高度树 | Minimum Height Trees
For an undirected graph with tree characteristics, we can choose any node as the root. The result gr ...
- 最小高度的树 Minimum Height Trees
2018-09-24 12:01:38 问题描述: 问题求解: 毫无疑问的一条非常好的题目,采用的解法是逆向的BFS,也就是从叶子节点开始遍历,逐步向中心靠拢,最终留下的叶子节点就是答案. publi ...
- 310. Minimum Height Trees -- 找出无向图中以哪些节点为根,树的深度最小
For a undirected graph with tree characteristics, we can choose any node as the root. The result gra ...
- 图论-BFS-最小高度的树 Minimum Height Trees
2018-09-24 12:01:38 问题描述: 对于一个具有树特征的无向图,我们可选择任何一个节点作为根.图因此可以成为树,在所有可能的树中,具有最小高度的树被称为最小高度树.给出这样的一个图,写 ...
- [LeetCode] 310. Minimum Height Trees 解题思路
For a undirected graph with tree characteristics, we can choose any node as the root. The result gra ...
- 【LeetCode】310. Minimum Height Trees 解题报告(Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 BFS 相似题目 参考资料 日期 题目地址:http ...
- leetcode.310最小高度树
对于一个具有树特征的无向图,我们可选择任何一个节点作为根.图因此可以成为树,在所有可能的树中,具有最小高度的树被称为最小高度树.给出这样的一个图,写出一个函数找到所有的最小高度树并返回他们的根节点. ...
随机推荐
- SQL Tuning 基础概述08 - SQL Tuning Advisor
SQL调优顾问 SQL Tuning Advisor的使用案例: 1.构建测试表T 2.定义调整任务 3.修改调整任务参数 4.执行调整任务 5.监控调整任务 6.查看调整任务建议 7.删除调整任务 ...
- Vertica集群扩容实验过程记录
需求: 将3个节点的Vertica集群扩容,额外增加3个节点,即扩展到6个节点的Vertica集群. 实验环境: RHEL 6.5 + Vertica 7.2.2-2 步骤: 1.三节点Vertica ...
- Apworks框架实战(五):EasyMemo的领域模型设计
在上一讲中,我们已经新建了一个聚合根对象Account,并已经可以开始设计领域模型了.在这一讲中,我们会着重介绍EasyMemo领域模型的分析和设计,并引入Visual Studio Ultimate ...
- JS魔法堂:不完全国际化&本地化手册 之 实战篇
前言 最近加入到新项目组负责前端技术预研和选型,其中涉及到一个熟悉又陌生的需求--国际化&本地化.熟悉的是之前的项目也玩过,陌生的是之前的实现仅仅停留在"有"的阶段而已. ...
- base的应用
------------父类 public class Person { public Person(string name,int age) { this.Na ...
- Index
我主要在研究.NET/C# 实现 PC IMERP 和 Android IMERP ,目的在解决企业通信中遇到的各类自动化问题 分布式缓存框架: Microsoft Velocity:微软自家分布 ...
- Windows下快速安装Flask的一次经历
前提: 1.已安装python版本(一般都是2.X) 2.已安装easy_install python安装,记得配置Python的环境变量,例如:我的直接在Path上加 G:\Python 验证安装P ...
- 9.6 MongoDB一
目录:ASP.NET MVC企业级实战目录 9.6.1 MongoDB简介 MongoDB是一个高性能,开源,无模式的文档型数据库,是当前NoSql数据库中比较热门的一种.它在许多场景下可用于替代传统 ...
- MySQL基础知识和操作(一)
- 扩展JS Date对象时间格式化功能
在自己JS代码中引入一下代码: Date.prototype.format =function(format) { var o = { "M+" : this.getMonth() ...