Welcome to Subscribe On Youtube
1973. Count Nodes Equal to Sum of Descendants
Description
Given the root of a binary tree, return the number of nodes where the value of the node is equal to the sum of the values of its descendants.
A descendant of a node x is any node that is on the path from node x to some leaf node. The sum is considered to be 0 if the node has no descendants.
Example 1:

Input: root = [10,3,4,2,1] Output: 2 Explanation: For the node with value 10: The sum of its descendants is 3+4+2+1 = 10. For the node with value 3: The sum of its descendants is 2+1 = 3.
Example 2:

Input: root = [2,3,null,2,null] Output: 0 Explanation: No node has a value that is equal to the sum of its descendants.
Example 3:

Input: root = [0] Output: 1 For the node with value 0: The sum of its descendants is 0 since it has no descendants.
Constraints:
- The number of nodes in the tree is in the range
[1, 105]. 0 <= Node.val <= 105
Solutions
Solution 2: Explicit Stack
Thinking
Each node is compared with the sum of every descendant. A fresh walk per node is quadratic. Post-order already has both subtree sums when a node is finished, so one traversal can test the node and pass the total upward.
$n$ reaches $10^5$. Post-order enters the left child first, so a left chain overflows the call stack before the sums are done. Values reach $10^5$, and a subtree sum can reach $10^{10}$, which does not fit in a 32-bit integer.
The descendant sum is known only after both children return. An explicit stack separates “expand the children” from “both children have returned,” and the completion step reads the two subtree sums. Those sums are 64-bit integers. When their total equals the node, the answer increases, and the node’s own value is added for its parent.
Each node is pushed once. A missing child contributes $0$.
-
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode() {} * TreeNode(int val) { this.val = val; } * TreeNode(int val, TreeNode left, TreeNode right) { * this.val = val; * this.left = left; * this.right = right; * } * } */ class Solution { private int ans; public int equalToDescendants(TreeNode root) { dfs(root); return ans; } private int dfs(TreeNode root) { if (root == null) { return 0; } int l = dfs(root.left); int r = dfs(root.right); if (l + r == root.val) { ++ans; } return root.val + l + r; } } // Solution 2 /** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode() {} * TreeNode(int val) { this.val = val; } * TreeNode(int val, TreeNode left, TreeNode right) { * this.val = val; * this.left = left; * this.right = right; * } * } */ class Solution { private static class Frame { TreeNode node; int state; Frame(TreeNode node, int state) { this.node = node; this.state = state; } } public int equalToDescendants(TreeNode root) { int ans = 0; Map<TreeNode, Long> sub = new IdentityHashMap<>(); Deque<Frame> stk = new ArrayDeque<>(); if (root != null) { stk.push(new Frame(root, 0)); } while (!stk.isEmpty()) { Frame cur = stk.pop(); TreeNode node = cur.node; if (cur.state == 0) { stk.push(new Frame(node, 1)); if (node.right != null) { stk.push(new Frame(node.right, 0)); } if (node.left != null) { stk.push(new Frame(node.left, 0)); } continue; } long l = node.left == null ? 0 : sub.get(node.left); long r = node.right == null ? 0 : sub.get(node.right); if (l + r == node.val) { ++ans; } sub.put(node, node.val + l + r); } return ans; } } -
/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode() : val(0), left(nullptr), right(nullptr) {} * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} * }; */ class Solution { public: int equalToDescendants(TreeNode* root) { int ans = 0; function<long long(TreeNode*)> dfs = [&](TreeNode* root) -> long long { if (!root) { return 0; } auto l = dfs(root->left); auto r = dfs(root->right); ans += l + r == root->val; return root->val + l + r; }; dfs(root); return ans; } }; // Solution 2 /** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode() : val(0), left(nullptr), right(nullptr) {} * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} * }; */ class Solution { public: int equalToDescendants(TreeNode* root) { int ans = 0; unordered_map<TreeNode*, long long> sub; vector<pair<TreeNode*, int>> stk; if (root) { stk.emplace_back(root, 0); } while (!stk.empty()) { auto [node, state] = stk.back(); stk.pop_back(); if (state == 0) { stk.emplace_back(node, 1); if (node->right) { stk.emplace_back(node->right, 0); } if (node->left) { stk.emplace_back(node->left, 0); } continue; } long long l = node->left ? sub[node->left] : 0; long long r = node->right ? sub[node->right] : 0; ans += l + r == node->val; sub[node] = node->val + l + r; } return ans; } }; -
# Definition for a binary tree node. # class TreeNode: # def __init__(self, val=0, left=None, right=None): # self.val = val # self.left = left # self.right = right class Solution: def equalToDescendants(self, root: Optional[TreeNode]) -> int: def dfs(root): if root is None: return 0 l, r = dfs(root.left), dfs(root.right) if l + r == root.val: nonlocal ans ans += 1 return root.val + l + r ans = 0 dfs(root) return ans # Solution 2 # Definition for a binary tree node. # class TreeNode: # def __init__(self, val=0, left=None, right=None): # self.val = val # self.left = left # self.right = right class Solution: def equalToDescendants(self, root: Optional[TreeNode]) -> int: ans = 0 stk = [(root, 0)] sub = {} while stk: node, state = stk.pop() if node is None: continue if state == 0: stk.append((node, 1)) if node.right is not None: stk.append((node.right, 0)) if node.left is not None: stk.append((node.left, 0)) continue l = sub[id(node.left)] if node.left is not None else 0 r = sub[id(node.right)] if node.right is not None else 0 if l + r == node.val: ans += 1 sub[id(node)] = node.val + l + r return ans -
/** * Definition for a binary tree node. * type TreeNode struct { * Val int * Left *TreeNode * Right *TreeNode * } */ func equalToDescendants(root *TreeNode) (ans int) { var dfs func(*TreeNode) int dfs = func(root *TreeNode) int { if root == nil { return 0 } l, r := dfs(root.Left), dfs(root.Right) if l+r == root.Val { ans++ } return root.Val + l + r } dfs(root) return } // Solution 2 /** * Definition for a binary tree node. * type TreeNode struct { * Val int * Left *TreeNode * Right *TreeNode * } */ func equalToDescendants(root *TreeNode) (ans int) { sub := map[*TreeNode]int{} type frame struct { node *TreeNode state int } stk := []frame{} if root != nil { stk = append(stk, frame{root, 0}) } for len(stk) > 0 { cur := stk[len(stk)-1] stk = stk[:len(stk)-1] node := cur.node if cur.state == 0 { stk = append(stk, frame{node, 1}) if node.Right != nil { stk = append(stk, frame{node.Right, 0}) } if node.Left != nil { stk = append(stk, frame{node.Left, 0}) } continue } l, r := 0, 0 if node.Left != nil { l = sub[node.Left] } if node.Right != nil { r = sub[node.Right] } if l+r == node.Val { ans++ } sub[node] = node.Val + l + r } return }