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.java
example:node
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的標籤是同樣的(當前節點也算是他的子樹節點)
輸出這樣一個數組就行。ide
簡單來講毫無頭緒。而且覺得這是個很複雜的題目。實際上看看下面的其餘人的代碼吧,簡潔高效。idea
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的實現:code
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; }