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

Leetcode 1519. Number of Nodes in the Sub-Tree With the Same Label (python)

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

题目

Leetcode 1519. Number of Nodes in the Sub-Tree With the Same Label (python)
Leetcode 1519. Number of Nodes in the Sub-Tree With the Same Label (python)

解法:

这个题目需要好好理解,首先题目没有给根几点,而只是给了根节点的值。同时提供的边是没有方向的,可能是parent指向child,也可以是child指向parent。

因为只提供了根节点的值和边,所以我们只能通过BFS来遍历整棵树,通过一个visited数组保证访问方向是从parent到child的。同时关于我们要求的答案,需要maintain一个count数组,因为都是lowercase,所以每行26的长度即可,这样方便后续的更新

同时这边利用了树形递归的方法,从child节点到parent节点逆向更新
详细的流程查看代码注释

class Solution:
    def countSubTrees(self, n: int, edges: List[List[int]], labels: str) -> List[int]:
        # create adjacent table
        d = collections.defaultdict(list)
        for edge in edges:
            d[edge[0]].append(edge[1])
            d[edge[1]].append(edge[0])
        
        # value at parents[ind] means node 'value' is the parent of node 'ind'
        # for example: [1,2] means 1 is the parent of 0, 2 is the parent of 1
        parents = [0] * n
        # initialize the parent of the root node 0 as -1
        parents[0] = -1
        # the row index of counts means the node value, every row means how many times of 'a'-'z' occurs in the node 'row' and its subtree.
        counts = [[0] * 26 for _ in range(n)]
        # visit_order represents the level order traversal of the tree
        visit_order = []
        
        q = collections.deque()
        q.append(0)
        # We use BFS to traversal the tree from node 0. the visited array is to make sure that we will visited the parent first. During BFS, we need to do two things: 1)store the parent of every node 2) update the label of current node in the counts array
        visited = [False] * n
        visited[0] = True
        while q:
            curr = q.popleft()
            visit_order.append(curr)
            # update the label of current node in the counts array
            label = labels[curr]
            counts[curr][ord(label)-ord('a')] += 1
            for nei in d[curr]:
                if not visited[nei]:
                    # store the parent node
                    parents[nei] = curr
                    q.append(nei)
                    visited[nei] = True
        # use 树形递推, use the reverse order from children to parent, and update the occurence of the label of the parent
        # note that we don't need to update the parent node 0, because it don't has parent
        for node in visit_order[::-1][:-1]:
            parent = parents[node]
            for i,num in enumerate(counts[node]):
                counts[parent][i] += num
        ans = []
        for i in range(n):
            label = labels[i]
            count = counts[i][ord(label)-ord('a')]
            ans.append(count)
        return ans