Distribute Coins in Binary Tree

Updated on 23 May, 2025
Distribute Coins in Binary Tree header image

Problem Statement

In this problem, you are given a binary tree where each node contains a certain number of coins. The tree has n nodes, and the sum of all coins in the nodes equals n. Your task is to redistribute the coins so that each node contains exactly one coin. The redistribution can occur through a series of moves, where one move involves transferring one coin between two adjacent nodes (viz., from a parent to its child or from a child to its parent).

You are required to determine and return the minimum number of moves necessary to achieve equal distribution of one coin per node across the entire tree.

Examples

Example 1

Input:

root = [3,0,0]

Output:

2

Explanation:

From the root of the tree, we move one coin to its left child, and one coin to its right child.

Example 2

Input:

root = [0,3,0]

Output:

3

Explanation:

From the left child of the root, we move two coins to the root [taking two moves]. Then, we move one coin from the root of the tree to the right child.

Constraints

  • The number of nodes in the tree is n.
  • 1 <= n <= 100
  • 0 <= Node.val <= n
  • The sum of all Node.val is n.

Approach and Intuition

Given the constraints and the problem setup, here is the intuition and approach to solving this problem:

  1. Essentially, the move operation is a method of balancing the excess or deficiency of coins between adjacent nodes.
  2. A key observation is the concept of "net balance" of a node:
    • If a node has more than one coin, it has an excess of coins, which it needs to pass to its neighbors.
    • If a node has zero coins, it has a deficit and needs to receive coins from its neighbors.
  3. The approach involves a recursive traversal (e.g., DFS) of the tree:
    • For each node, calculate how many coins it needs or has in excess after satisfying its own requirement of one coin.
    • A positive balance indicates excess coins that need to be passed up to the parent or to the children.
    • A negative balance indicates a deficit, so this node requires coins from its parent or can accept excess coins from its children.
  4. The recursion will calculate and return the number of moves required for each node based on its balance:
    • When visiting a node, recursively determine the number of moves required for its left and right children.
    • Adjust the coin distribution based on the balances returned by the children.
    • The total number of moves for the current node is the sum of the moves required by its children plus any moves needed to transfer excess coins to or from this node.
  5. Start the recursive calculation from the root to cover the entire tree.
  6. Each transfer of a coin from a node to its adjacent node counts as one move.

The recursive process ensures that each node, after accounting for transfers, has exactly one coin, achieving the goal in the minimum number of moves by optimizing local balances progressively through the tree structure.

Solutions

  • C++
  • Java
  • Python
cpp
class Solution {
public:
    int coinDistribution(TreeNode* rootNode) {
        totalMoves = 0;
        explore(rootNode);
        return totalMoves;
    }

private:
    int totalMoves; // Store the total number of moves
    int explore(TreeNode* node) {
        if (node == nullptr) return 0;

        int leftExcess = explore(node->left); // excess coins in left child
        int rightExcess = explore(node->right); // excess coins in right child

        totalMoves += abs(leftExcess) + abs(rightExcess); // accumulate the moves needed

        return (node->val - 1) + leftExcess + rightExcess; // calculate current node excess
    }
};

The provided solution is a C++ class designed to determine the number of moves needed to distribute coins in a binary tree such that each node has exactly one coin. Here's a quick breakdown of how this solution operates:

  • The class Solution has a private integer member totalMoves which keeps track of the total number of coin redistribution moves required.

  • The coinDistribution function is the public interface of the class, taking a pointer to the tree's root node as its argument. The function first sets totalMoves to zero, then calls the explore function starting from the root node and returns the value of totalMoves.

  • The private member function explore works recursively to calculate the excess or deficit of coins at each node in the tree:

    • If the current node is nullptr, it returns 0, indicating no excess or deficiency.

    • It recursively calculates the excess coins for both the left and right children of the current node.

    • The totalMoves is incremented by the sum of the absolute values of the left and right excesses. This increment represents the number of moves needed to balance the left and right children with the current node.

    • Finally, it returns the excess coins at the current node, calculated as (node->val - 1) plus the left and right excess values. The -1 accounts for the coin that is to remain with the current node.

This solution efficiently calculates the minimum moves required by balancing coins from the bottom of the tree upwards, ensuring each node ends with exactly one coin after all redistributions.

java
class Solution {

    private int totalMoves;

    public int distributeCoins(TreeNode node) {
        totalMoves = 0;
        traverse(node);
        return totalMoves;
    }

    private int traverse(TreeNode node) {
        if (node == null) return 0;

        int leftExcess = traverse(node.left);
        int rightExcess = traverse(node.right);

        totalMoves += Math.abs(leftExcess) + Math.abs(rightExcess);

        return node.val - 1 + leftExcess + rightExcess;
    }
}

The problem set involves redistributing coins such that every node of a binary tree has exactly one coin using the minimum number of moves. In this Java solution, a recursion-based approach is used to achieve the objective.

  • Start with defining a private variable totalMoves to keep track of the number of moves made during redistribution.
  • Create a public function distributeCoins that initializes totalMoves to zero and starts the recursion by calling the traverse function on the tree's root. This function returns the totalMoves counter when completed.
  • Implement a private helper function traverse that uses recursion to navigate through the tree. If the node is null, it returns zero, representing no excess coins to move.
  • For each node, calculate the excess coins in the left and right child through recursive calls to traverse.
  • Adjust totalMoves by adding the absolute value of the excess coins from both left and right children. This sum represents the minimum moves needed to make the current node balanced.
  • Return the excess from the current node which is the node value minus one (to make it balanced) added to the excess coins of left and right children combined. This value represents the net excess (positive or negative) that will be returned to the node's parent.

The essence of the solution lies in the recursive traversal and adjustment of the coin balance from the bottom of the tree to the top, ensuring minimum moves by only handling excess coins at each node.

python
class Solution:
    def coinDistribution(self, root: Optional[TreeNode]) -> int:
        self.total_moves = 0

        def traverse(node):
            if node == None:
                return 0
            
            # Compute the balance of coins in left and right children nodes
            coins_left = traverse(node.left)
            coins_right = traverse(node.right)

            # Update total moves by adding the movements needed for balance
            self.total_moves += abs(coins_left) + abs(coins_right)

            # Calculate the number of spare coins current node has to give or needs
            return (node.val - 1) + coins_left + coins_right

        traverse(root)

        return self.total_moves

The problem Distribute Coins in Binary Tree involves adjusting the number of coins on each node of a binary tree so that every node has exactly one coin. The challenge tasks you with calculating the minimum number of movements required to achieve this balance.

The provided Python solution involves a class Solution with a method coinDistribution that takes root, a TreeNode representing the root of the binary tree. The approach focuses on a depth-first search traversal of the tree to redistribute and count the movements of coins as follows:

  • Initialize a variable self.total_moves to count the required movements to balance the coins.

  • Define and use a helper function, traverse, which:

    • Returns 0 if the node is None (base case for recursion)
    • Recursively calculates the required movements of coins in both left and right child nodes of the current node.
    • Uses the absolute value of coins required or surplus in the left and right child nodes to update self.total_moves.
    • Determines the net coin balance for the current node and returns it, indicating how many coins need to be moved in or out.
  • Call the helper function traverse starting from the root.

  • Finally, return self.total_moves which now contains the minimum number of moves required to distribute the coins properly across the tree nodes.

This solution efficiently computes the result by traversing each node exactly once, making it performant with a complexity closely tied to the number of nodes in the tree.

Comments

No comments yet.