首页 > 其他分享 >【LeetCode 310】最小高度树

【LeetCode 310】最小高度树

时间:2024-03-18 13:55:39浏览次数:19  
标签:head degree int 310 最小 LeetCode ++ tail 节点

题目描述

原题链接: LeetCode.310 最小高度树

解题思路

  • 最小高度树的叶子节点肯定是初始只有一条边的节点;
  • 广度优先遍历, 逐批将当前叶子节点移除, 再将移除后新的叶子节点入队;
  • 所有节点全部入队时, 当前队列中剩余的最后一批"叶子节点"就是答案;
  • 坦白说这题的严格思路证明没想过, 第一反应直接想到了解法并且提交通过, 更严谨的证明过程感兴趣再去看题解吧, 包括求树中最长路径得到答案的解法也有待了解。

解题代码

  /**
   * 拓补排序解法, 逐批移除度为1的节点, 所有节点全部入队时最后一批入队的节点就是答案
   * 执行用时: 10 ms , 在所有 Java 提交中击败了 99.15% 的用户
   * 内存消耗: 54.16 MB , 在所有 Java 提交中击败了 72.91% 的用户
   */
  public List<Integer> findMinHeightTrees(int n, int[][] edges) {
      List<Integer> ans = new ArrayList<>();
      if (n < 3) {
          for (int i = 0; i < n; i++) {
              ans.add(i);
          }
          return ans;
      }
      // 生成邻接表并统计节点的度
      List<Integer>[] graph = new List[n];
      for (int i = 0; i < n; i++) {
          graph[i] = new ArrayList<>();
      }
      int[] degree = new int[n];
      for (int[] edge : edges) {
          int u = edge[0], v = edge[1];
          graph[u].add(v);
          graph[v].add(u);
          degree[u]++;
          degree[v]++;
      }
      int[] queue = new int[n];
      int head = 0, tail = 0;
      for (int i = 0; i < n; i++) {
          if (degree[i] == 1) {
              queue[tail++] = i;
          }
      }
      while (tail > head) {
          int size = tail - head;
          while (size-- > 0) {
              int u = queue[head++];
              for (int v : graph[u]) {
                  degree[v]--;
                  if (degree[v] == 1) {
                      queue[tail++] = v;
                  }
              }
          }
          if (tail == n) {
              // 所有节点都已入队, 当前队列中所有节点的度都只剩1, 都可以作为最小高度树的根
              while (tail > head) {
                  ans.add(queue[head++]);
              }
              break;
          }
      }
      return ans;
  }

标签:head,degree,int,310,最小,LeetCode,++,tail,节点
From: https://www.cnblogs.com/coding-memory/p/18080254

相关文章

  • [Java·算法·中等] LeetCode21. 合并两个有序链表
    人不走空                                          ......
  • 【LeetCode 2684】矩阵中移动的最大次数
    题目描述原题链接:2684矩阵中移动的最大次数解题思路每次只能向右侧的下一列紧挨着的三行严格大的格子移动;能移动到i列代表能移动i次,这取决于i-1列可到达的矩阵位置的状态,即可以整列递推相邻列是否可移动到达;两个方向递推的思路:三个(col+1)位置的状态可以逆推出一个(c......
  • 【机器学习-04】最小二乘法的推导过程及使用方法(python代码实现)
    最小二乘法是一种常用的数据拟合方法,它可以通过最小化残差平方和来找到数据的最佳拟合线。有了上述内容铺垫之后,本文将介绍最小二乘法的推导过程,并提供使用Python实现最小二乘法的代码示例。1.模型及方程组的矩阵形式改写  首先,我们对......
  • 代码随想录算法训练营第十天|LeetCode 20.有效的括号、1047.删除字符串中的所有相邻重
    20.有效的括号题目链接:https://leetcode.cn/problems/valid-parentheses/description/解题思路:题目转化:三种类型的括号,需要做匹配匹配规则是:左右括号的类型要匹配、数量要一致,而且要按照顺序匹配例子是:“()”、“(){}[]”、“(([]))”条件转化:按照顺序匹配:......
  • LCR 088. 使用最小花费爬楼梯
    数组的每个下标作为一个阶梯,第i个阶梯对应着一个非负数的体力花费值cost[i](下标从0开始)。每当爬上一个阶梯都要花费对应的体力值,一旦支付了相应的体力值,就可以选择向上爬一个阶梯或者爬两个阶梯。请找出达到楼层顶部的最低花费。在开始时,你可以选择从下标为0或1的元素......
  • lc907 子数组的最小值之和
    给定数组arr[n],求所有子数组中最小值的和,答案对1e9+7取模。1<=n<=30000;1<=arr[i]<=30000考虑每个数作为最小值对应的子数组有多少个,计算对答案的贡献,而子数组的个数可以用单调栈来维护。数组元素可能相同,为了避免重复计数,用半开半闭区间。classSolution{public:ints......
  • leetcode 21 合并两个有序链表
    https://www.bilibili.com/video/BV1xa411A76q?p=4&vd_source=cdfcf738e0429ec2cffe4778dd8dd0e4 #迭代#https://blog.csdn.net/m0_61661179/article/details/127205244classSolution:defmergeTwoLists(self,list1:Optional[ListNode],list2:Optional[List......
  • LeetCode精选101刷题必备(C++)-附详细分类及解体说明
    分享一本leetcode刷题必备,互联网就业必备的免费书,非常好,值得推荐。感谢作者高畅无私整理和免费分享。本书介绍    本书分为算法和数据结构两大部分,又细分了十五个章节,详细讲解了刷LeetCode时常用的技巧。我把题目精简到了101道,一是呼应了本书的标题,二是不想让读......
  • LeetCode题练习与总结:有效的数独
    一、题目请你判断一个 9x9的数独是否有效。只需要根据以下规则,验证已经填入的数字是否有效即可。数字 1-9 在每一行只能出现一次。数字 1-9 在每一列只能出现一次。数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。(请参考示例图)注意:一个有效的数独(......
  • LeetCode题练习与总结:搜索插入位置
    一、题目给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。请必须使用时间复杂度为O(logn)的算法。二、解题思路初始化两个指针,left指向数组的起始位置,right指向数组的结束位置。当left小于等......