leetcode 1519. Number of Nodes in the Sub-Tree With the Same Label(子树中相同Label的节点个数)

leetcode 1519. Number of Nodes in the Sub-Tree With the Same Label(子树中相同Label的节点个数)_第1张图片
不一定是二叉树,共有n个节点,edges代表了互相连接的顶点形成的边,
每个节点有一个label, label是小写英文字母。
第 i 个字母表示第 i 个节点的标签。

问在同一子树中,相同标签的节点个数。
需要返回一个长度为n的数组,ans[i] 处的值表示在以节点i为根的子树中,和节点i 的标签相同的节点个数。

思路:

要找子树的每个节点的话,首先想到DFS。

现在的问题是怎么记录下子节点的label, 和这个label出现的次数。
可以用HashMap来记录,当然由于字母只有26个,可以用长度为26的数组记录下每个label出现的次数。

子节点遍历完之后,会得到一些字母上对应的次数>0了,
这个子树的根节点,要选出它的label对应的次数,放在ans[i]里面。

当然,首先还是要构建无向图,
然后要记录下每个节点是否已经被访问过,可以用visited数组记录,
由于没有环的存在,也可以只看child是不是上一节点即可。

class Solution {
    List<Integer>[] graph;
    int[] ans;

    public int[] countSubTrees(int n, int[][] edges, String labels) {
        graph = new ArrayList[n];
        ans = new int[n];
        HashSet<Character> chLabels = new HashSet<>();

        for(int i = 0; i < n; i++) graph[i] = new ArrayList<>();

        for(int[] edge : edges) {
            graph[edge[0]].add(edge[1]);
            graph[edge[1]].add(edge[0]);
        }

        chLabels.add(labels.charAt(0));
        dfs(-1, 0, labels);

        return ans;
    }

    int[] dfs(int pre, int node, String labels) {
        int[] tmp = new int[26];
        
        for(int child : graph[node]) {
            if(pre == child) continue;
            int[] res = dfs(node, child,labels);
            for(int i = 0; i < 26; i++) tmp[i] += res[i];
        }
        ans[node] = ++tmp[labels.charAt(node)-'a'];
        return tmp;
    }
}

你可能感兴趣的:(leetcode,leetcode,算法,深度优先)