【LeetCode】310. Minimum Height Trees 最小高度树(Medium)(JAVA)

【LeetCode】310. Minimum Height Trees 最小高度树(Medium)(JAVA)

题目地址: https://leetcode.com/problems/minimum-height-trees/

题目描述:

A tree is an undirected graph in which any two vertices are connected by exactly one path. In other words, any connected graph without simple cycles is a tree.

Given a tree of n nodes labelled from 0 to n - 1, and an array of n - 1 edges where edges[i] = [ai, bi] indicates that there is an undirected edge between the two nodes ai and bi in the tree, you can choose any node of the tree as the root. When you select a node x as the root, the result tree has height h. Among all possible rooted trees, those with minimum height (i.e. min(h))  are called minimum height trees (MHTs).

Return a list of all MHTs’ root labels. You can return the answer in any order.

The height of a rooted tree is the number of edges on the longest downward path between the root and a leaf.

Example 1:

Input: n = 4, edges = [[1,0],[1,2],[1,3]]
Output: [1]
Explanation: As shown, the height of the tree is 1 when the root is the node with label 1 which is the only MHT.

Example 2:

Input: n = 6, edges = [[3,0],[3,1],[3,2],[3,4],[5,4]]
Output: [3,4]

Example 3:

Input: n = 1, edges = []
Output: [0]

Example 4:

Input: n = 2, edges = [[0,1]]
Output: [0,1]

Constraints:

  • 1 <= n <= 2 * 10^4
  • edges.length == n - 1
  • 0 <= a_i, b_i < n
  • a_i != b_i
  • All the pairs (a_i, b_i) are distinct.
  • The given input is guaranteed to be a tree and there will be no repeated edges.

题目大意

树是一个无向图,其中任何两个顶点只通过一条路径连接。 换句话说,一个任何没有简单环路的连通图都是一棵树。

给你一棵包含 n 个节点的数,标记为 0 到 n - 1 。给定数字 n 和一个有 n - 1 条无向边的 edges 列表(每一个边都是一对标签),其中 edges[i] = [ai, bi] 表示树中节点 ai 和 bi 之间存在一条无向边。

可选择树中任何一个节点作为根。当选择节点 x 作为根节点时,设结果树的高度为 h 。在所有可能的树中,具有最小高度的树(即,min(h))被称为 最小高度树 。

请你找到所有的 最小高度树 并按 任意顺序 返回它们的根节点标签列表。

树的 高度 是指根节点和叶子节点之间最长向下路径上边的数量。

解题方法

  1. 这一题主要是要知道叶子节点的依赖为 1
  2. 从叶子节点开始往里面找出最高的层级,也就是层序遍历
class Solution {
    public List<Integer> findMinHeightTrees(int n, int[][] edges) {
        List<Integer> res = new ArrayList<>();

        if (n == 1 || edges.length == 0) {
            res.add(0);
            return res;
        }

        int[] degree = new int[n];
        Map<Integer, List<Integer>> map = new HashMap<>();
        for (int i = 0; i < edges.length; i++) {
            putNum(map, edges[i][0], edges[i][1]);
            putNum(map, edges[i][1], edges[i][0]);
            degree[edges[i][0]]++;
            degree[edges[i][1]]++;
        }

        Queue<Integer> queue = new LinkedList<>();
        for (int i = 0; i < degree.length; i++) {
            if (degree[i] == 1) queue.offer(i);
        }
        while (queue.size() > 0) {
            res = new ArrayList<>();
            int size = queue.size();
            for (int i = 0; i < size; i++) {
                Integer cur = queue.poll();
                res.add(cur);
                List<Integer> list = map.get(cur);
                for (int next : list) {
                    degree[next]--;
                    if (degree[next] == 1) queue.offer(next);
                }
            }
        }
        return res;
    }
    
    public void putNum(Map<Integer, List<Integer>> map, int key, int value) {
        List<Integer> temp = map.get(key);
        if (temp == null) {
            temp = new ArrayList<>();
            map.put(key, temp);
        }
        temp.add(value);
    }
}

执行耗时:18 ms,击败了43.93% 的Java用户
内存消耗:40.4 MB,击败了94.93% 的Java用户

欢迎关注我的公众号,LeetCode 每日一题更新
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值