首页 > 其他分享 >图:310.最小高度数, 题解

图:310.最小高度数, 题解

时间:2024-09-16 13:02:14浏览次数:10  
标签:degree int 题解 310 最小 edge res push 节点

310. 最小高度树 - 力扣(LeetCode)

参考题解:

算法逻辑:算法的核心思路是逐层剪去叶子节点,直到剩下的节点是最小高度树的根

示例:

假设有如下的树结构:

    0
   / \
  1   2
     / \
    3   4

初始时,叶子节点是134,剪掉这些叶子节点后,树变成:

    0
     \
      2

再次剪掉叶子节点2,最终剩下的节点是0,0就是最小高度树的根节点。

相同的边,还有一种最小高度数的情况是:

      2
   / \  \
  3   4 0
           \
            1

初始时剪掉叶子节点3,4,1;再次剪掉叶子节点0,最终剩下的节点是2,2就是最小高度数的根节点。

具体代码如下:

class Solution {
public:
    vector<int> findMinHeightTrees(int n, vector<vector<int>>& edges) {
        vector<int> res;
        // 如果只有一个节点,那么它就是最小高度树
        if (n == 1) {
            res.push_back(0);
            return res;
        }

        // 建立各个节点的出度表
        vector<int> degree(n, 0);
        // 建立图关系,在每个节点的列表中存储相连节点
        vector<vector<int>> map(n);
        for (const auto& edge : edges) {
            degree[edge[0]]++;
            degree[edge[1]]++; // 出度++
            map[edge[0]].push_back(edge[1]); // 添加相邻节点
            map[edge[1]].push_back(edge[0]);
        }

        // 建立队列
        queue<int> q;
        // 把所有出度为1的节点,也就是叶子节点入队
        for (int i = 0; i < n; ++i) {
            if (degree[i] == 1) {
                q.push(i);
            }
        }

        // 循环条件是队列不空
        while (!q.empty()) {
            res.clear(); // 每层循环都要new一个新的结果集合
            int size = q.size(); // 每一层的节点的数量
            for (int i = 0; i < size; ++i) {
                int cur = q.front();
                q.pop();
                res.push_back(cur); // 将当前节点加入结果集

                for (int neighbor : map[cur]) {
                    degree[neighbor]--;
                    if (degree[neighbor] == 1) {
                        q.push(neighbor); // 如果是叶子节点,入队
                    }
                }
            }
        }

        return res; // 返回最后一次保存的列表
    }
};

 

标签:degree,int,题解,310,最小,edge,res,push,节点
From: https://www.cnblogs.com/spp20/p/18416199

相关文章

  • 【洛谷 P1216】[USACO1.5] [IOI1994]数字三角形 Number Triangles 题解(动态规划)
    [USACO1.5][IOI1994]数字三角形NumberTriangles题目描述观察下面的数字金字塔。写一个程序来查找从最高点到底部任意处结束的路径,使路径经过数字的和最大。每一步可以走到左下方的点也可以到达右下方的点。在上面的样例中,从的路径产生了最大权值。输入格式第一个行一个正整数......
  • 题解:P9938 [USACO21OPEN] Acowdemia II B
    首先根据每篇出版物构建一个资历比较矩阵\(g\),其中\(g_{a,b}=1\)表示研究员\(a\)比\(b\)资历更高。遍历每篇出版物,识别出第一个降序的名字,然后假定该名字之后的所有研究员资历都比当前名字对应的研究员资历高即可。代码:#include<bits/stdc++.h>usingnamespacestd;......
  • 题解:P9951 [USACO20FEB] Swapity Swap B
    奶牛的排列经过\(x\)次后会回到原来的位置,理解以下:\([a_1,a_2]\)的牛翻转两次就会回到原来的位置,\([b_1,b_2]\)的牛翻转两次也会回到原来的位置,所以原来奶牛的排列经过一定次数的旋转后一定会回到原来位置。我们只要先模拟得出多少次后第\(i\)位的奶牛会回到原来的位置,然后......
  • 题解:P9953 [USACO20OPEN] Social Distancing II B
    解决思路:根据奶牛的位置对数组进行排序。计算相邻健康奶牛和感染奶牛之间的最小距离。这个距离值减一用来估计感染传播的半径。(确保了感染奶牛之间的距离在当前半径下不会导致传播给其他健康奶牛。)遍历排序后的奶牛列表,找到每一段连续感染奶牛的区域,并计算这些区域中可能需要的......
  • 区间检测题解
    记录\(pre_i\)为\(a_i\)上一次出现的位置。每一次求\([L,R]\)范围内是否有相同的数即\(pre_L\)到\(pre_R\)中的最大值是否小于\(L\)。注意到\(pre_1\)到\(pre_{L-1}\)中最大数一定小于\(L\),所以求\([L,R]\)范围内是否有相同的数即\(pre_1\)到\(pre_R\)中的......
  • 题解:P9957 [USACO20DEC] Stuck in a Rut B
    由于\(x,y\leq10^9\),我们无法模拟每个时间段。因此,我们需要尝试判断两头牛何时会相交。一个重要的观察是,牛不能后退,所以两头牛发生碰撞的唯一方式是\(n[x]>e[x]\)且\(n[y]<e[y]\)。可以按牛的起始坐标进行排序,然后模拟这些碰撞。代码:#include<bits/stdc++.h>using......
  • 题解:P3113 [USACO14DEC] Marathon G
    用线段树维护子路径的长度和这条子路径上删除一个点能够减少的最大距离。那么,修改就修改线段树上对应位置的值,查询就求这一段子路径的距离和子路径上删除一个点能够减少的最大距离,两者相减即可得到答案。代码:#include<bits/stdc++.h>usingnamespacestd;typedefpair<int,in......
  • 题解:P10961 划分大理石
    设\(f_x\)表示拼成\(x\)后,当前的大理石最多还能剩下几块,不能拼成就是\(-1\)。状态转移(当前考虑的大理石价值为\(i\),有\(x\)块):\(f_j=x(f_j\ge0)\)本来就可以拼成,那么现在的大理石都可以剩下。\(f_j=f_{j-i}-1(f_j=-1,j\gei,f_{j-i}>0)\)本来不能拼成,但用了一块就能拼......
  • 最小生成树
    最小生成树Prim朴素PrimO(n2)堆优化PrimO(mlogn)KruskalO(mlogm)Prim//模板intn;//n表示点数intg[N][N];//邻接矩阵,存储所有边intdist[N];//存储其他点到当前最小生成树的距离boolst[N];//存储每个点是否已经在生成树......
  • AGC026D Histogram Coloring 题解
    [AGC026D]HistogramColoring题解给定\(n\)列的网格,每列高为\(h_i\),将每个格子染色成红色或蓝色,使得每个\(2\times2\)的区域都恰好有两个蓝格子和两个红格子,求方案数(对\(10^9+7\)取模)。\(1\leqn\leq100,1\leqh_i\leq10^9\)性质为了方便讲述,先假设\(h_i=h_{i+......