欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

LeetCode 1519. Number of Nodes in the Sub-Tree With the Same Label

程序员文章站 2022-07-15 11:35:02
...

given a tree, containing n nodes and n-1 edges. the root is node 0 and each node has a label(character), that means The node with the number i has the label labels[i].
The edges array is given on the form edges[i] = [ai, bi], which means there is an edge between nodes ai and bi in the tree. (ai bi are both numbers)
Return an array of size n where ans[i] is the number of nodes in the subtree of the ith node which have the same label as node i.

example:

LeetCode 1519. Number of Nodes in the Sub-Tree With the Same Label
Input: n = 7, edges = [[0,1],[0,2],[1,4],[1,5],[2,3],[2,6]], labels = “abaedcd”
Output: [2,1,1,1,1,1,1]

idea:
这道题目就是很别扭,最后让我们输出一个数组
ans[i]代表第i号node的子树种有多少个标签和这个Node的标签是一样的(当前节点也算是他的子树节点)
输出这样一个数组就行。

简单来说毫无头绪。并且以为这是个很复杂的题目。实际上看看下面的其他人的代码吧,简洁高效。

class Solution {
    public int[] countSubTrees(int n, int[][] edges, String labels) {
        HashMap<Integer, List<Integer>> map = new HashMap<>();
        for (int[] edge: edges) {
            map.computeIfAbsent(edge[0], k -> new ArrayList<>()).add(edge[1]);
            map.computeIfAbsent(edge[1], k -> new ArrayList<>()).add(edge[0]);
        }
        int[] ans = new int[n];
        dfs(map, 0, -1, labels, ans); //dfs contains: map, labels, ans, current node and its parent
        return ans;
    }
    
    private int[] dfs(HashMap<Integer, List<Integer>> map, int node, int parent, String labels, int[] ans) { //return the ans based on curNode and parent
        int[] cnt = new int[26]; //we need to maintain a new
        char c = labels.charAt(node);
        for (int child: map.get(node)) {
            if (child != parent) {  //since it is a tree, we don't need visit array/hashmap to check if we visited it before.
                int[] sub = dfs(map, child, node, labels, ans);
                for (int i = 0; i < 26; i++) {
                    cnt[i] += sub[i];
                }
            }
        }
        cnt[c - 'a']++; //add current node as one
        ans[node] = cnt[c - 'a']; //update ans
        return cnt; //return cnt instead of ans
    }
}

下面的代码是一般的带着visit的实现:

    public int[] countSubTrees(int n, int[][] edges, String labels) {
        Map<Integer, List<Integer>> g = new HashMap<>();
        for (int[] e : edges) {
            g.computeIfAbsent(e[0], l -> new ArrayList<>()).add(e[1]);
            g.computeIfAbsent(e[1], l -> new ArrayList<>()).add(e[0]);
        }
        int[] ans = new int[n];
        Set<Integer> seen = new HashSet<>();
        dfs(g, 0, labels, ans, seen);
        return ans;
    }
    private int[] dfs(Map<Integer, List<Integer>> g, int node, String labels, int[] ans, Set<Integer> seen) {
        int[] cnt = new int[26];
        if (seen.add(node)) {
            char c = labels.charAt(node);
            for (int child : g.getOrDefault(node, Collections.emptyList())) {
                int[] sub = dfs(g, child, labels, ans, seen);
                for (int i = 0; i < 26; ++i) {
                    cnt[i] += sub[i];
                }
            }
            ++cnt[c - 'a'];
            ans[node] = cnt[c - 'a'];
        }
        return cnt;
    }