From c80c1f3fa728ee0c2a4b57a9b6027e4668299cd2 Mon Sep 17 00:00:00 2001 From: ShusenTang Date: Wed, 13 Nov 2019 21:35:22 +0800 Subject: [PATCH] Create 310. Minimum Height Trees.md --- solutions/310. Minimum Height Trees.md | 56 ++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 solutions/310. Minimum Height Trees.md diff --git a/solutions/310. Minimum Height Trees.md b/solutions/310. Minimum Height Trees.md new file mode 100644 index 0000000..835dd80 --- /dev/null +++ b/solutions/310. Minimum Height Trees.md @@ -0,0 +1,56 @@ +# [310. Minimum Height Trees](https://leetcode.com/problems/minimum-height-trees/) +# 思路 +给定一个可以表示成树的无向图, 可知存在很多种表示法方法, 要求树高最小的树的根节点. + +brute force思路就是从每个结点出发分别bfs把树高求出来, 然后返回树高最小的对应的根节点就行了. 但是这样要对每个结点进行bfs, 时间复杂度很高会超时. + +题目给了一个提示: How many MHTs can a graph have at most? 稍加思考可以得出最多有两棵, +而且根节点就是直径(即距离最长的两个叶子间的距离)路径的中心结点, 如果直径为奇数那么只有一棵, 如果直径为偶数则有两棵. +所以我么可以先把这个直径求出来: 从任意点bfs到深度最大叶子,再从该叶子节点bfs到最远节点, +第二遍bfs的时候记录每个点的父节点, 最后就可以得到直径路径, 然后返回直径路径的中心结点就行了. + +上面的思路需要两次bfs, 时间复杂度为O(n). 其实此题还有个更加简便的方法求直径的中心结点: +* 去掉当前图的所有叶子节点,重复此操作直到只剩下一个或两个结点。 + +相当于是从最外面向内部进行dfs, 这个思路有点类似拓扑排序, 即题目[210. Course Schedule II](https://leetcode.com/problems/course-schedule-ii/), 可 +参考[210题解](https://github.com/ShusenTang/LeetCode/blob/master/solutions/210.%20Course%20Schedule%20II.md)中的bfs思路. + +# C++ +``` C++ +class Solution { +public: + vector findMinHeightTrees(int n, vector>& edges) { + vector>G(n, vector()); + for(int i = 0; i < edges.size(); i++){ + G[edges[i][0]].push_back(edges[i][1]); + G[edges[i][1]].push_back(edges[i][0]); + } + + queueleafs; // 存放当前所有叶子 + for(int i = 0; i < n; i++) + if(G[i].size() <= 1) leafs.push(i); + + while(n > 2){ + int cur_size = leafs.size(); + n -= cur_size; + while(cur_size--){ + int leaf = leafs.front(); leafs.pop(); + int to = G[leaf][0]; + for(int j = 0; j < G[to].size(); j++) + if(G[to][j] == leaf){ + G[to].erase(G[to].begin()+j); + break; + } + if(G[to].size() == 1) leafs.push(to); + } + } + + vectorres; + while(!leafs.empty()){ + res.push_back(leafs.front()); + leafs.pop(); + } + return res; + } +}; +```