Solving Leetcode Interviews in Seconds with AI: Find Subtree Sizes After Changes
Introduction
In this blog post, we will explore how to solve the LeetCode problem "3331" using AI. LeetCode is a popular platform for preparing for coding interviews, and with the help of AI tools like Chatmagic, we can generate solutions quickly and efficiently - helping you pass the interviews and get the job offer without having to study for months.
Problem Statement
You are given a tree rooted at node 0 that consists of n nodes numbered from 0 to n - 1. The tree is represented by an array parent of size n, where parent[i] is the parent of node i. Since node 0 is the root, parent[0] == -1. You are also given a string s of length n, where s[i] is the character assigned to node i. We make the following changes on the tree one time simultaneously for all nodes x from 1 to n - 1: Find the closest node y to node x such that y is an ancestor of x, and s[x] == s[y]. If node y does not exist, do nothing. Otherwise, remove the edge between x and its current parent and make node y the new parent of x by adding an edge between them. Return an array answer of size n where answer[i] is the size of the subtree rooted at node i in the final tree. Example 1: Input: parent = [-1,0,0,1,1,1], s = "abaabc" Output: [6,3,1,1,1,1] Explanation: The parent of node 3 will change from node 1 to node 0. Example 2: Input: parent = [-1,0,4,0,1], s = "abbba" Output: [5,2,1,1,1] Explanation: The following changes will happen at the same time: The parent of node 4 will change from node 1 to node 0. The parent of node 2 will change from node 4 to node 1. Constraints: n == parent.length == s.length 1 <= n <= 105 0 <= parent[i] <= n - 1 for all i >= 1. parent[0] == -1 parent represents a valid tree. s consists only of lowercase English letters.
Explanation
- Simultaneous Parent Update: Iterate through nodes 1 to
n-1. For each nodex, traverse upwards to find the nearest ancestorywith the same characters[x] == s[y]. Update the parent ofxaccordingly, storing these updates. Apply these updates to theparentarray simultaneously after processing all nodes.- Subtree Size Calculation: After the parent updates, perform a Depth-First Search (DFS) or Breadth-First Search (BFS) to build the adjacency list representation of the modified tree. Then, use another DFS to calculate the subtree size for each node.
- Complexity: O(N) time complexity, where N is the number of nodes. O(N) space complexity to store the adjacency list, subtree sizes, and updated parents.
Code
def subtree_sizes(parent, s):
n = len(parent)
updated_parent = parent[:] # Create a copy for simultaneous updates
# Find new parents
for i in range(1, n):
curr = i
ancestor = parent[i]
closest_ancestor = -1
while ancestor != -1:
if s[curr] == s[ancestor]:
closest_ancestor = ancestor
break
curr = ancestor
ancestor = parent[ancestor]
if closest_ancestor != -1:
updated_parent[i] = closest_ancestor
# Build adjacency list from updated parents
adj = [[] for _ in range(n)]
for i in range(1, n):
adj[updated_parent[i]].append(i)
# Calculate subtree sizes
subtree_size = [0] * n
def dfs(node):
subtree_size[node] = 1
for child in adj[node]:
dfs(child)
subtree_size[node] += subtree_size[child]
dfs(0)
return subtree_size