Find Subtree Sizes After Changes - Problem

Imagine you have a family tree where each person has a unique character assigned to them. Now, here's the twist: every person wants to be closer to their ancestor who shares the same character!

You're given a tree rooted at node 0 with n nodes numbered from 0 to n-1. The tree structure is represented by a parent array where parent[i] is the parent of node i (with parent[0] = -1 since node 0 is the root). Each node i has a character s[i] assigned to it.

Here's what happens simultaneously for all nodes from 1 to n-1:

  • Each node x looks for the closest ancestor y that has the same character (s[x] == s[y])
  • If such an ancestor exists, node x abandons its current parent and becomes a direct child of ancestor y
  • If no such ancestor exists, the node stays put

Your task is to return an array where answer[i] represents the size of the subtree rooted at node i after all these family relocations are complete!

Input & Output

example_1.py โ€” Basic Tree Transformation
$ Input: parent = [-1,0,1,2], s = "abbc"
โ€บ Output: [4,2,1,1]
๐Ÿ’ก Note: Node 2 (character 'b') finds ancestor node 1 (also 'b') and becomes its child. Node 3 ('c') has no 'c' ancestors so stays under node 2. Final tree: 0->1->3, 0->2, giving sizes [4,2,1,1].
example_2.py โ€” No Changes Needed
$ Input: parent = [-1,0,0,1,1], s = "abcde"
โ€บ Output: [5,3,1,1,1]
๐Ÿ’ก Note: All characters are unique, so no node can find an ancestor with the same character. The tree structure remains unchanged, and subtree sizes are calculated normally.
example_3.py โ€” Multiple Relocations
$ Input: parent = [-1,0,1,2,3], s = "aaaaa"
โ€บ Output: [5,1,1,1,1]
๐Ÿ’ก Note: All nodes have character 'a'. Node 1 stays under root 0. Nodes 2,3,4 all move to be direct children of root 0 (closest 'a' ancestor). Final tree: 0 has children [1,2,3,4].

Constraints

  • n == parent.length == s.length
  • 1 โ‰ค n โ‰ค 105
  • parent[0] == -1
  • 0 โ‰ค parent[i] โ‰ค n - 1 for i โ‰  0
  • parent represents a valid tree
  • s consists of only lowercase English letters

Visualization

Tap to expand
Tree Reorganization ProcessBefore: Original Tree0: CEO (a)1: Dev (b)2: Dev (b)Wants to move up!3: QA (c)After: Reorganized Tree0: CEO (a)Moved!1: Dev (b)2: Dev (b)3: QA (c)Team Sizes: [4, 2, 1, 1]Key Insight: Each person reports to their nearest ancestor with the same specialtyAlgorithm Steps:1. DFS Traversal: Visit nodes while maintaining character stacks2. Ancestor Lookup: Check stack top for same character ancestor (O(1))3. Tree Rebuild: Create new parent-child relationships4. Size Calculation: Count subtree sizes in the final structure
Understanding the Visualization
1
Original Structure
Start with the initial parent-child relationships
2
Find Matches
Each employee looks upward for a manager with the same specialty
3
Relocate
Employees move to report directly to their preferred manager
4
Count Teams
Calculate the size of each manager's team in the new structure
Key Takeaway
๐ŸŽฏ Key Insight: Using character-indexed stacks during DFS enables O(1) ancestor lookup, making the entire algorithm run in optimal O(n) time with just one tree traversal.
Asked in
Google 23 Amazon 18 Meta 15 Microsoft 12
23.4K Views
Medium Frequency
~25 min Avg. Time
847 Likes
Ln 1, Col 1
Smart Actions
๐Ÿ’ก Explanation
AI Ready
๐Ÿ’ก Suggestion Tab to accept Esc to dismiss
// Output will appear here after running code
Code Editor Closed
Click the red button to reopen