列表

详情


100354. 统计好节点的数目

现有一棵 无向 树,树中包含 n 个节点,按从 0n - 1 标记。树的根节点是节点 0 。给你一个长度为 n - 1 的二维整数数组 edges,其中 edges[i] = [ai, bi] 表示树中节点 ai 与节点 bi 之间存在一条边。

如果一个节点的所有子节点为根的 子树 包含的节点数相同,则认为该节点是一个 好节点

返回给定树中 好节点 的数量。

子树 指的是一个节点以及它所有后代节点构成的一棵树。

 

 

示例 1:

输入:edges = [[0,1],[0,2],[1,3],[1,4],[2,5],[2,6]]

输出:7

说明:

树的所有节点都是好节点。

示例 2:

输入:edges = [[0,1],[1,2],[2,3],[3,4],[0,5],[1,6],[2,7],[3,8]]

输出:6

说明:

树中有 6 个好节点。上图中已将这些节点着色。

示例 3:

输入:edges = [[0,1],[1,2],[1,3],[1,4],[0,5],[5,6],[6,7],[7,8],[0,9],[9,10],[9,12],[10,11]]

输出:12

解释:

除了节点 9 以外其他所有节点都是好节点。

 

提示:

相似题目

N 叉树的最大深度

原站题解

去查看

上次编辑到这里,代码来自缓存 点击恢复默认模板
class Solution { public: int countGoodNodes(vector<vector<int>>& edges) { } };

javascript 解法, 执行用时: 750 ms, 内存消耗: 129.4 MB, 提交时间: 2024-11-14 09:31:52

/**
 * @param {number[][]} edges
 * @return {number}
 */
var countGoodNodes = function(edges) {
    const n = edges.length + 1;
    const g = Array.from({ length: n }, () => []);
    for (const [x, y] of edges) {
        g[x].push(y);
        g[y].push(x);
    }
    let res = 0;
    const dfs = (node, parent) => {
        let valid = true;
        let treeSize = 0;
        let subTreeSize = 0;
        for (const child of g[node]) {
            if (child !== parent) {
                const size = dfs(child, node);
                if (subTreeSize === 0) {
                    subTreeSize = size;
                } else if (size !== subTreeSize) {
                    valid = false;
                }
                treeSize += size;
            }
        }
        if (valid) {
            res++;
        }
        return treeSize + 1;
    };

    dfs(0, -1);
    return res;
};

rust 解法, 执行用时: 83 ms, 内存消耗: 23.5 MB, 提交时间: 2024-11-14 09:31:36

impl Solution {
    pub fn count_good_nodes(edges: Vec<Vec<i32>>) -> i32 {
        let n = edges.len() + 1;
        let mut g = vec![vec![]; n];
        let mut res = 0;
        for edge in edges {
            let (x, y) = (edge[0] as usize, edge[1] as usize);
            g[x].push(y);
            g[y].push(x);
        }

        fn dfs(node: usize, parent: isize, g: &Vec<Vec<usize>>, res: &mut i32) -> usize {
            let mut valid = true;
            let mut tree_size = 0;
            let mut sub_tree_size = 0;

            for &child in &g[node] {
                if child != parent as usize {
                    let size = dfs(child, node as isize, g, res);
                    if sub_tree_size == 0 {
                        sub_tree_size = size;
                    } else if size != sub_tree_size {
                        valid = false;
                    }
                    tree_size += size;
                }
            }
            if valid {
                *res += 1;
            }
            tree_size + 1
        }

        dfs(0, -1, &g, &mut res);
        res
    }
}

java 解法, 执行用时: 105 ms, 内存消耗: 114.3 MB, 提交时间: 2024-08-12 09:43:33

class Solution {
    public int countGoodNodes(int[][] edges) {
        int n = edges.length + 1;
        List<Integer>[] g = new ArrayList[n];
        Arrays.setAll(g, i -> new ArrayList<>());
        for (int[] e : edges) {
            int x = e[0];
            int y = e[1];
            g[x].add(y);
            g[y].add(x);
        }
        dfs(0, -1, g);
        return ans;
    }

    private int ans;

    private int dfs(int x, int fa, List<Integer>[] g) {
        int size = 1;
        int pre = 0;
        boolean ok = true;
        for (int y : g[x]) {
            if (y == fa) {
                continue; // 不能递归到父节点
            }
            int sz = dfs(y, x, g);
            if (pre > 0 && sz != pre) {
                ok = false;
            }
            pre = sz; // 记录上一个儿子子树的大小
            size += sz;
        }
        if (ok) {
            ans++;
        }
        return size;
    }
}

cpp 解法, 执行用时: 830 ms, 内存消耗: 325.1 MB, 提交时间: 2024-08-12 09:43:04

class Solution {
public:
    int countGoodNodes(vector<vector<int>>& edges) {
        int n = edges.size() + 1;
        vector<vector<int>> g(n);
        for (auto& e : edges) {
            int x = e[0], y = e[1];
            g[x].push_back(y);
            g[y].push_back(x);
        }

        int ans = 0;
        auto&& dfs = [&](auto&& dfs, int x, int fa) -> int {
            int size = 1, pre = 0;
            bool ok = true;
            for (int y : g[x]) {
                if (y == fa) {
                    continue; // 不能递归到父节点
                }
                int sz = dfs(dfs, y, x);
                if (pre > 0 && sz != pre) {
                    ok = false;
                }
                pre = sz; // 记录上一个儿子子树的大小
                size += sz;
            }
            ans += ok;
            return size;
        };
        dfs(dfs, 0, -1);
        return ans;
    }
};

golang 解法, 执行用时: 451 ms, 内存消耗: 43.5 MB, 提交时间: 2024-08-12 09:41:21

func countGoodNodes(edges [][]int) (ans int) {
	n := len(edges) + 1
	g := make([][]int, n)
	for _, e := range edges {
		x, y := e[0], e[1]
		g[x] = append(g[x], y)
		g[y] = append(g[y], x)
	}
	var dfs func(int, int) int
	dfs = func(x, fa int) int {
		size, pre, ok := 1, 0, true
		for _, y := range g[x] {
			if y == fa {
				continue // 不能递归到父节点
			}
			sz := dfs(y, x)
			if pre > 0 && sz != pre {
				ok = false
			}
			pre = sz // 记录上一个儿子子树的大小
			size += sz
		}
		if ok {
			ans++
		}
		return size
	}
	dfs(0, -1)
	return
}

python3 解法, 执行用时: 629 ms, 内存消耗: 73.1 MB, 提交时间: 2024-08-12 09:41:06

class Solution:
    def countGoodNodes(self, edges: List[List[int]]) -> int:
        n = len(edges) + 1
        g = [[] for _ in range(n)]
        for x, y in edges:
            g[x].append(y)
            g[y].append(x)

        ans = 0
        # x 开始节点,fa 父节点
        def dfs(x: int, fa: int) -> int:
            size, pre, ok = 1, 0, True
            for y in g[x]:
                if y == fa:
                    continue  # 不能递归到父节点
                sz = dfs(y, x)
                if 0 < pre != sz:
                    ok = False
                pre = sz  # 记录上一个儿子子树的大小
                size += sz
            nonlocal ans
            ans += ok
            return size
        dfs(0, -1)
        return ans

上一题