Trees · Binary Tree Fundamentals

Binary Tree Children Sum Property

Enforcing, at every node, that its value equals the sum of its immediate children's values (with a lone child treated as contributing its own value) by pushing a value change down when a node's stated value is too high, then re-deriving every internal node's value bottom-up on the way back up so no adjustment made deeper in the tree is left stale higher up.

  • 7 min read
  • 11 practice questions
  • 2 graded problems
On this page
  1. Description
  2. The approach (repairing a tree)
  3. A second flavor: checking without changing anything
  4. Where you'll see it
  5. Which tool for which job?
  6. Common mistakes
  7. Check yourself
  8. Key takeaways
  9. Quick revise
  10. Practice

Description

A tree has the children sum property when every node's value equals the sum of its children's values. Leaves are exempt, since they have no children. Two tasks come with it. Checking whether a tree already has the property is one read-only pass. Repairing a tree that doesn't, by only ever increasing values, takes a walk down and a walk back up.

We'll go from simple to more technical:

  1. The pattern: the repair - push down, recurse, sum up.
  2. A second flavor: the read-only check.
  3. Where rollup rules like this hold in production.
  4. The mistakes: skipping the upward pass, writing to missing children, and leaves.

The approach (repairing a tree)

You may only increase values. So when a node is bigger than its children's sum, you can't lower it. Instead, raise a child to the node's value and let the fix carry on below. When a node's children already add up to at least its value, the node simply takes their sum. Then, after both subtrees are repaired, set each node to its children's sum on the way back up. That last step matters, because a change deep down can make every ancestor wrong.

Here's a tree before and after the repair:

After

Before

20

4

6

1

2

28

22

6

20

2

After

Before

20

4

6

1

2

28

22

6

20

2

StepAt nodeWhat happens
120 (root)children sum 4 + 6 = 10, less than 20: raise the left child from 4 to 20
220 (was 4)children sum 1 + 2 = 3, less than 20: raise its left child from 1 to 20
3the leaves 20, 2 and 6nothing to fix
4back at the left childits children sum to 20 + 2: set it to 22
5back at the rootits children sum to 22 + 6: set it to 28

Without steps 4 and 5, the root would still say 20 while its children add up to 28.

Java

void changeTree(TreeNode root) {
    if (root == null) return;
    int childSum = (root.left != null ? root.left.val : 0) + (root.right != null ? root.right.val : 0);
    if (childSum >= root.val) {
        root.val = childSum;                          // children already dominate - adopt their sum
    } else if (root.left != null) {
        root.left.val = root.val;                       // push the excess down onto whichever child exists
    } else if (root.right != null) {
        root.right.val = root.val;
    }
    changeTree(root.left);
    changeTree(root.right);
    // bottom-up: re-derive this node's value now that its children are finalized
    int total = (root.left != null ? root.left.val : 0) + (root.right != null ? root.right.val : 0);
    if (root.left != null || root.right != null) root.val = total;
}

Python

def change_tree(root: TreeNode | None) -> None:
    if root is None:
        return
    child_sum = (root.left.val if root.left else 0) + (root.right.val if root.right else 0)
    if child_sum >= root.val:
        root.val = child_sum               # children already dominate - adopt their sum
    elif root.left:
        root.left.val = root.val           # push the excess down onto whichever child exists
    elif root.right:
        root.right.val = root.val
    change_tree(root.left)
    change_tree(root.right)
    # bottom-up: re-derive this node's value now that its children are finalized
    if root.left or root.right:
        root.val = (root.left.val if root.left else 0) + (root.right.val if root.right else 0)

A second flavor: checking without changing anything

Checking whether a tree already has the property is much simpler. There's no pushing and no second pass. Each node compares its value with its children's sum, and every subtree must pass too. In the example, the "After" tree passes and the "Before" tree fails at the root.

Java

boolean checkChildrenSumProperty(TreeNode node) {
    if (node == null) return true;
    if (node.left == null && node.right == null) return true;   // a leaf trivially satisfies it
    int childSum = (node.left != null ? node.left.val : 0) + (node.right != null ? node.right.val : 0);
    return node.val == childSum
        && checkChildrenSumProperty(node.left)
        && checkChildrenSumProperty(node.right);
}

Python

def check_children_sum_property(node: TreeNode | None) -> bool:
    if node is None:
        return True
    if node.left is None and node.right is None:
        return True                        # a leaf trivially satisfies it
    child_sum = (node.left.val if node.left else 0) + (node.right.val if node.right else 0)
    return (node.val == child_sum
            and check_children_sum_property(node.left)
            and check_children_sum_property(node.right))

The leaf check is what makes this correct. A leaf's children sum to 0. Without the check, every leaf would have to hold 0 to pass.

Where you'll see it

Budgets and ledgers often follow this rule: a department's budget is the sum of its teams' budgets. When someone edits a team's number, every total above it has to be recomputed, bottom up. Auditing whether the totals already add up is the simpler check.

Which tool for which job?

You needUse
Does every node equal its children's sum?one pass, leaves always pass
Make it hold by only increasing valuespush down the shortfall, recurse, then sum up
Does every node equal its whole subtree's sum?return subtree sums from one recursion
Totals that keep changingrecompute along the path to the root on each edit
Large valuessums in long

Common mistakes

MistakeWhat happensDo this instead
Skipping the upward passparents don't reflect deeper changesset each node to its children's sum after recursing
Writing to a missing childNullPointerException, or a made-up nodepush onto a child that exists
Checking leaves against 0every non-zero leaf failsleaves always satisfy it
A subtree-sum helper at every nodeO(n^2) on chainsreturn sums from one recursion
int sumsthe root overflowslong

Check yourself

Try to answer before opening each one - recalling beats re-reading.

1. A repair pushes a node's value down to a child and never comes back to that node. What goes wrong?

Show answer

The push can set off more pushes further down, and those raise values below the child. The node never sees them, so it no longer equals its children's sum. In the example, the root would stay 20 while its children add up to 28.

2. A repair writes root.left.val = root.val without checking that root.left exists. What happens on a node with only a right child?

Show answer

A NullPointerException, because there's no left child to write to. A node with one child must push onto the child it actually has. Check which one exists first.

3. A check computes the children's sum as 0 for leaves and compares it with the leaf's value. What does it report for a correct tree?

Show answer

That the tree fails, as soon as any leaf holds a non-zero value. Almost every real tree has such leaves. Treat a node with no children as an automatic pass.

Key takeaways

  • The repair has two parts: push values down on the way in, then set each node to its children's sum on the way back up.
  • The upward pass isn't optional. A deep change only reaches the ancestors through it.
  • A node with one child pushes onto that child, never onto a missing one.
  • The read-only check is one pass with no changes, but it needs an explicit leaf case.

Quick revise

The whole skill on one page, for the night before an interview.

Everything from the lesson and the deep dive on one page. Skim it before practice or an interview, and open the full lesson for anything that doesn't ring a bell.

Pick the tool

You needUse
Checkone pass, leaves pass
Repair (only increases)push down, recurse, sum up
Sum treereturn subtree sums
Live totalsadd deltas to ancestors

Snippets worth knowing by heart

Java

void fix(TreeNode n) {
    if (n == null || (n.left == null && n.right == null)) return;
    long kids = (n.left != null ? n.left.val : 0) + (n.right != null ? n.right.val : 0);
    if (kids < n.val) { if (n.left != null) n.left.val = n.val; else n.right.val = n.val; }   // existing child
    fix(n.left); fix(n.right);
    n.val = (n.left != null ? n.left.val : 0) + (n.right != null ? n.right.val : 0);         // sum up
}

Python

def holds(node) -> bool:
    if node is None or (node.left is None and node.right is None):
        return True                        # leaves always pass
    kids = (node.left.val if node.left else 0) + (node.right.val if node.right else 0)
    return node.val == kids and holds(node.left) and holds(node.right)

The traps

  • No upward pass: parents keep stale sums after deeper changes. Set each node to its children's sum after recursing.
  • Writing to a missing child: you crash or invent a node. Push the difference onto a child that exists.
  • Leaves checked against 0: every non-zero leaf fails. Leaves always satisfy the property.
  • Subtree-sum helpers at every node: a chain costs O(n^2). Return sums from one recursion.
  • int overflow: the root's sum can exceed an int. Use long.

Staff-level points, one line each

  • The repair held on 500 random trees and never decreased a value.
  • It's valid, not minimal.
  • 1,024 leaves of 3,000,000: an int root became -1222967296; long: 3,072,000,000.
  • Sum-tree check with a helper on a 400-node chain: 160,398 calls.
  • Live rollups: add deltas along the path to the root.

Say it in an interview

  • "Checking is one read-only pass; leaves always satisfy it."
  • "To repair, I push any shortfall down, fix the subtrees, then set each node to its children's sum."
  • "Values only go up, so the fix never breaks a node it already fixed."
  • "The root ends up as the sum of the leaves, so I'd use a long."

Practice

This skill comes with 11 multiple-choice questions that tell you which misconception a wrong answer reveals and 2 graded problems. Your answers are graded and your mastery is tracked, so you'll know when the skill holds up. Running code and saving progress need a free account.

Practice Binary Tree Children Sum Property free

Children Sum Property in Binary Tree

MediumProCoding problemJava · Python

A binary tree satisfies the children sum property when, for every node with at least one child, the node's value equals the sum of its immediate children's values (a node with only one child needs that child's value to equal its own; leaves trivially satisfy it).

The full statement, the examples and the hidden test suite are part of AI Proof Engineers Pro.

Check Children Sum Property

MediumProCoding problemJava · Python

A binary tree satisfies the children sum property when, for every node with at least one child, the node's value equals the sum of its immediate children's values (a node with only one child needs that child's value to equal its own; leaves trivially satisfy it regardless of…

The full statement, the examples and the hidden test suite are part of AI Proof Engineers Pro.

Practice Binary Tree Children Sum Property free

No card needed. Lessons, practice questions and easy problems are free forever.

Free plan, no card · 7-day Pro trial · Cancel anytime