{x}
blog image

Delete Tree Nodes

Solution Explanation for Delete Tree Nodes

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:

  1. 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.

  2. Depth-First Search (DFS): A recursive DFS function dfs(i) is the core of the solution. For each node i, it performs the following:

    • It calculates the sum (s) of the node's value and the sum of values in its subtree.
    • It counts the number of nodes (m) in the subtree, including the node itself.
    • If s (the sum of values in the subtree) is zero, it means the entire subtree should be deleted, so m is set to 0.
    • The function returns the pair (s, m).
  3. 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.