一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第5天,点击查看活动详情 。
树是一个无向图,其中任何两个顶点只通过一条路径连接。 换句话说,一个任何没有简单环路的连通图都是一棵树。
给你一棵包含 n 个节点的树,标记为 0 到 n - 1 。给定数字 n 和一个有 n - 1 条无向边的 edges 列表(每一个边都是一对标签),其中 edges[i] = [ai, bi] 表示树中节点 ai 和 bi 之间存在一条无向边。
可选择树中任何一个节点作为根。当选择节点 x 作为根节点时,设结果树的高度为 h 。在所有可能的树中,具有最小高度的树(即,min(h))被称为 最小高度树 。
请你找到所有的 最小高度树 并按 任意顺序 返回它们的根节点标签列表。
树的 高度 是指根节点和叶子节点之间最长向下路径上边的数量。 示例 1:
输入:n = 4, edges = [[1,0],[1,2],[1,3]]
输出:[1]
解释:如图所示,当根是标签为 1 的节点时,树的高度是 1 ,这是唯一的最小高度树。
示例 2:
输入:n = 6, edges = [[3,0],[3,1],[3,2],[3,4],[5,4]]
输出:[3,4]
拓扑排序
由于树的高度由根节点到叶子节点之间的最大距离构成,假设树中距离最长的两个节点为 ,它们之间的距离为 ,假设 到 的路径为,根据方法一的证明已知最小树的根节点一定为该路径中的中间节点,我们尝试删除最外层的度为 1 的节点 后,则可以知道路径中与 相邻的节点 此时也变为度为 1 的节点,此时我们再次删除最外层度为 1 的节点直到剩下根节点为止。
实际做法如下:
- 首先找到所有度为 1 的节点压入队列,此时令节点剩余计数 ;
- 同时将当前 计数减去出度为 1 的节点数目,将最外层的度为 1 的叶子节点取出,并将与之相邻的节点的度减少,重复上述步骤将当前节点中度为 1 的节点压入队列中;
- 重复上述步骤,直到剩余的节点数组 时,此时剩余的节点即为当前高度最小树的根节点。
var findMinHeightTrees = function(n, edges) {
const ans = [];
if (n === 1) {
ans.push(0);
return ans;
}
const degree = new Array(n).fill(0);
const adj = new Array(n).fill(0).map(() => new Array());
for (const edge of edges) {
adj[edge[0]].push(edge[1]);
adj[edge[1]].push(edge[0]);
degree[edge[0]]++;
degree[edge[1]]++;
}
const queue = [];
for (let i = 0; i < n; i++) {
if (degree[i] === 1) {
queue.push(i);
}
}
let remainNodes = n;
while (remainNodes > 2) {
const sz = queue.length;
remainNodes -= sz;
for (let i = 0; i < sz; i++) {
const curr = queue.shift();
for (const v of adj[curr]) {
degree[v]--;
if (degree[v] === 1) {
queue.push(v);
}
}
}
}
while (queue.length) {
ans.push(queue.shift());
}
return ans;
};
复杂度分析
时间复杂度:O(n)O(n)O(n),其中 nnn 是为节点的个数。图中边的个数为 n−1n-1n−1,因此建立图的关系需要的时间复杂度为 O(n)O(n)O(n),通过广度优先搜索需要的时间复杂度为 O(n+n−1)O(n + n - 1)O(n+n−1),求最长路径的时间复杂度为 O(n)O(n)O(n),因此总的时间复杂度为 O(n)O(n)O(n)。
空间复杂度:O(n)O(n)O(n),其中 nnn 是节点的个数。由于题目给定的图中任何两个顶点都只有一条路径连接,因此图中边的数目刚好等于 n−1n-1n−1,用邻接表构造图所需的空间刚好为 O(2×n)O(2 \\times n)O(2×n),存储每个节点的距离和父节点均为 O(n)O(n)O(n),使用广度优先搜索时,队列中最多有 nnn 个元素,所需的空间也为 O(n)O(n)O(n),因此空间复杂度为 O(n)O(n)O(n)。
- 时间复杂度:,其中 n 是为节点的个数。图中边的个数为 ,因此建立图的关系需要的时间复杂度为 ,通过广度优先搜索需要的时间复杂度为 ,求最长路径的时间复杂度为 ,因此总的时间复杂度为 。
- 空间复杂度:,其中 是节点的个数。由于题目给定的图中任何两个顶点都只有一条路径连接,因此图中边的数目刚好等于 ,用邻接表构造图所需的空间刚好为 ,存储每个节点的距离和父节点均为 ,使用广度优先搜索时,队列中最多有 个元素,所需的空间也为 ,因此空间复杂度为 。