[LeetCode] 310. Minimum Height Trees 解题思路
2016-01-12 00:37
239 查看
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
You can assume that no duplicate edges will appear in
Example 1:
Given
return
Example 2:
Given
return
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.
问题:给定一个拥有树性质的无向图,图的每一个节点都可以视为一棵树的根节点。在所有可能的树中,找出高度最小的树,并返回他们的树根。
视某个节点为树根节点,求这棵树的树高。
对所有节点进行上面的求解,得到 n 个树高,其中高度最小的树的树根即为原题目的解。
对于1,如何求解节点 A 为树根的树高?
假设已知 A 的所有相邻节点分别为树根的各个子树的树高,那么 A根的树高等于 已知的各个子树树高中的最大值 加一。方程式表达如下,即状态转换方程:
height(A) = max(height(A.next0), height(A.next2),... height(A.nextk)) + 1
对于2, 存在大量重复计算。可以借助表格,将已计算的树分支高度保存下来后续使用,避免重复计算。将当前节点以及其中一个相邻节点组合分支方向,求得该分支高度后存入 map<string, int> direc_height 中,其中 direc 有这两个节点组成作为 key ,height 表示高度。
若不使用表格优化,时间复杂度为 O(V*E)。使用表格,相当于进行了剪枝,会快不少。跑 LeetCode 的大集合 V = 1000, E =2000 ,测试耗时是 820ms,可惜没能过 submit 要求。
View Code
参考资料:
C++ Solution. O(n)-Time, O(n)-Space, LeetCode OJ
Format
The graph contains
nnodes which are labeled from
0to
n - 1. You will be given the number
nand 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.
问题:给定一个拥有树性质的无向图,图的每一个节点都可以视为一棵树的根节点。在所有可能的树中,找出高度最小的树,并返回他们的树根。
思路一 :
求最小高度的树,实际上是一个求最优解题目。求最优解,我首先想到的是动态规划(DP)思路。这个题目也确实满足 DP 的两个主要性质:overlapping substructure & optimal substructure 。思路比较直观:视某个节点为树根节点,求这棵树的树高。
对所有节点进行上面的求解,得到 n 个树高,其中高度最小的树的树根即为原题目的解。
对于1,如何求解节点 A 为树根的树高?
假设已知 A 的所有相邻节点分别为树根的各个子树的树高,那么 A根的树高等于 已知的各个子树树高中的最大值 加一。方程式表达如下,即状态转换方程:
height(A) = max(height(A.next0), height(A.next2),... height(A.nextk)) + 1
对于2, 存在大量重复计算。可以借助表格,将已计算的树分支高度保存下来后续使用,避免重复计算。将当前节点以及其中一个相邻节点组合分支方向,求得该分支高度后存入 map<string, int> direc_height 中,其中 direc 有这两个节点组成作为 key ,height 表示高度。
若不使用表格优化,时间复杂度为 O(V*E)。使用表格,相当于进行了剪枝,会快不少。跑 LeetCode 的大集合 V = 1000, E =2000 ,测试耗时是 820ms,可惜没能过 submit 要求。
class TNode{ public: int val; unordered_set<TNode*> neighbours; TNode(int val){ this->val = val; } }; vector<int> findMinHeightTrees(int n, vector<pair<int, int>>& edges) { map<int, TNode*> val_node; for (int i = 0 ; i < n ; i++){ TNode* tmp = new TNode(i); val_node[i] = tmp; } for (int i = 0 ; i < edges.size(); i++){ pair<int, int> pp = edges[i]; val_node[pp.first]->neighbours.insert(val_node[pp.second]); val_node[pp.second]->neighbours.insert(val_node[pp.first]); } map<int, TNode*>::iterator m_iter; while(val_node.size() > 2){ // obtain all leaves in current graph; list<TNode*> listg; for ( m_iter = val_node.begin(); m_iter != val_node.end(); m_iter++){ if(m_iter->second->neighbours.size() == 1){ listg.push_back(m_iter->second); } } // remove all leaves list<TNode*>::iterator l_iter; for(l_iter = listg.begin(); l_iter != listg.end(); l_iter++){ TNode* p = (*(*l_iter)->neighbours.begin()); p->neighbours.erase(*l_iter); (*l_iter)->neighbours.erase(p); val_node.erase((*l_iter)->val); } } vector<int> res; for ( m_iter = val_node.begin(); m_iter != val_node.end(); m_iter++){ res.push_back(m_iter->first); } return res; }
View Code
参考资料:
C++ Solution. O(n)-Time, O(n)-Space, LeetCode OJ
相关文章推荐
- 第01章 信息系统基础 之 信息系统工程总体规划
- 分治法(一)
- Package Control Messages
- POJ 3253 Fence Repair
- 写一个Android输入法01——最简步骤
- IOS网络Socke(客户端,服务器端)t的简单介绍
- 作为一个服务端后台开发,我起码要懂得这些
- DFT算法的理解和实现,望各位高手指点指点(谢谢)
- Partitioner 的简单应用
- 国内免费(开源)CMS系统大全
- 互联网公司笔试面试准备以及注意事项
- C#中DllImport用法汇总
- IT英语
- UITabBarControllerDemo 一个最基本到标签控制器
- 怎样写好简历
- 2016/01/11开始学习git:查看仓库状态和修改文件
- Java学习笔记(2)——字节流
- New UI-获取手机屏幕尺寸与分辨率,屏幕适配,横竖屏问题
- 一道关于Linux系统下fork系统调用的面试题
- Yii2实现表单客户端验证提示信息出现在指定位置