This problem involves traversing a tree and deleting subtrees whose node values sum to zero. The solution uses Depth-First Search (DFS) to efficiently accomplish this.
Approach:
Graph Representation: The input parent
array represents a tree structure. We first transform this into an adjacency list representation (g
in the code), where g[i]
contains a list of the children of node i
.
Depth-First Search (DFS): A recursive DFS function dfs(i)
is the core of the solution. For each node i
, it performs the following:
s
) of the node's value and the sum of values in its subtree.m
) in the subtree, including the node itself.s
(the sum of values in the subtree) is zero, it means the entire subtree should be deleted, so m
is set to 0.(s, m)
.Root Node Processing: The DFS starts at the root node (node 0). The second element of the returned pair from dfs(0)
represents the number of nodes remaining after the deletion.
Time Complexity:
The DFS function visits each node exactly once. Therefore, the time complexity is O(n), where n is the number of nodes in the tree.
Space Complexity:
The space complexity is dominated by the recursion stack during the DFS and the adjacency list. In the worst case (a skewed tree), the recursion stack can have a depth of O(n). The adjacency list also uses O(n) space. Therefore, the overall space complexity is O(n).
Code Explanation (Python):
class Solution:
def deleteTreeNodes(self, nodes: int, parent: List[int], value: List[int]) -> int:
def dfs(i):
s, m = value[i], 1 # Initialize sum and count for the current node
for j in g[i]: # Iterate through children of node i
t, n = dfs(j) # Recursively calculate sum and count for child subtree
s += t # Add child subtree sum to current node sum
m += n # Add child subtree count to current node count
if s == 0: # Check if the subtree sum is 0
m = 0 # Delete subtree by setting count to 0
return (s, m) # Return sum and count for the subtree
g = defaultdict(list) # Create an adjacency list to represent the tree
for i in range(1, nodes): # Build the adjacency list from the parent array
g[parent[i]].append(i)
return dfs(0)[1] # Start DFS from the root node (0) and return the remaining node count
The other language implementations (Java, C++, Go) follow the same algorithmic approach, with variations in syntax and data structures. The core logic of the DFS and the tree representation remains consistent across all implementations.