目录
一.题目原型
二.题目思路
三.代码实现
一.题目原型
二.题目思路
首先,我们看了样例,发现这个树并不是二叉树,是多叉树。
然后,我们可能想到的解法是:根据题目的意思,就挨个节点遍历bfs,统计下每个节点的高度,然后用map存储起来,后面查询这个高度的集合里最小的就可以了。
但是这样会超时的。
于是我们看图(题目介绍里面的图)分析一下,发现,越是靠里面的节点越有可能是最小高度树。
所以,我们可以这样想,我们可以倒着来。
我们从边缘开始,先找到所有出度为1的节点,然后把所有出度为1的节点进队列,然后不断地bfs,最后找到的就是两边同时向中间靠近的节点,那么这个中间节点就相当于把整个距离二分了,那么它当然就是到两边距离最小的点啦,也就是到其他叶子节点最近的节点了。
然后,就可以写代码了。
三.代码实现
1.通过遍历 edges ,构建度数表和邻接图
2.每次把度数为 1 的节点加入队列
3.广度遍历队列,把邻接图中的节点度数减一,当其度数为1时,将其入队
4.res数组每一层都更新一次,所以最后一次保留的就是使得高度最小的节点
class Solution {
private:// 找最小高度,最短路径想到BFS// 两端烧香求中点
public:vector<int> findMinHeightTrees(int n, vector<vector<int>>& edges) {if (n == 1) return {0};vector<int> res; // 每个节点的度数vector<int> degree(n);// 建立无向邻接图vector<vector<int>> map(n);for (int i = 0; i < edges.size(); i++) {int v1 = edges[i][0];int v2 = edges[i][1];degree[v1]++;degree[v2]++;map[v1].push_back(v2);map[v2].push_back(v1);}// 把度为1的节点入队queue<int> q;for (int i = 0; i < n; i++) {if (degree[i] == 1) q.push(i);}// BFSwhile (!q.empty()) {// 清理当前层的节点res.clear();int size = q.size();while (size--) {int cur = q.front();q.pop();res.push_back(cur);// 减小对应度数degree[cur]--;for (auto i : map[cur]) {degree[i]--;if (degree[i] == 1) {q.push(i);}}}} return res;}
};