Given the root of a binary tree with n nodes, where each node contains a certain number of candies, and the total number of candies across all nodes is n.
In one move, we can select two adjacent nodes and transfer one candy from one node to the other. The transfer can occur between a parent and child in either direction. Find the minimum number of moves required to ensure that every node in the tree has exactly one candy.
Examples:
Input:
Output: 6 Explanation: Move 1 candy from root to root->left node Move 1 candy from root to root->right node Move 1 candy from root->right node to root->right->left node Move 1 candy from root to root->right child Move 1 candy from root->right node to root->right->right node Move 1 candy from root to root->right node So, total 6 moves required.
Input:
Output: 4 Explanation: Move 1 candy from root to left child Move 1 candy from root->right->left node to root->right node Move 1 candy from root->right node to root->right->right node Move 1 candy from root->right->left node to root->right node So, total 4 moves required.
[Expected Approach - 1] Using Recursion - O(n) Time and O(h) Space
The idea is to use recursion to traverse the tree from leaf to root and consecutively balance all of the nodes. To balance a node, the number of candy at that node must be 1.
There can be two cases:
If a node needs candies, if the node of the tree has 0 candies then we should push a candy from its parent onto the node.
If the node has more than 1 candy. ex. 4 candies (an excess of 3), then we should push 3 candies off the node to its parent.
So, the total number of moves from that leaf to or from its parent is excess = abs(numCandies - 1). Once a node is balanced, we never have to consider this node again in the rest of our calculation.
C++
#include<iostream>usingnamespacestd;// Node StructureclassNode{public:intdata;Node*left;Node*right;Node(intx){data=x;left=right=nullptr;}};// function to find the number of// moves to distribute all of the candiesintdistCandyUtil(Node*root,int&ans){if(root==nullptr)return0;// Traverse left subtreeintl=distCandyUtil(root->left,ans);// Traverse right subtreeintr=distCandyUtil(root->right,ans);ans+=abs(l)+abs(r);// Return number of moves to balance// current nodereturnroot->data+l+r-1;}// Function to find the number of movesintdistCandy(Node*root){intans=0;distCandyUtil(root,ans);returnans;}intmain(){// Representation of given Binary Tree// 5// / \// 0 0// / \// 0 0Node*root=newNode(5);root->left=newNode(0);root->right=newNode(0);root->right->left=newNode(0);root->right->right=newNode(0);cout<<distCandy(root);return0;}
Java
// Node StructureclassNode{publicintdata;publicNodeleft,right;publicNode(intx){data=x;left=right=null;}}classGFG{//function to find the number of// moves to distribute all of the candiesstaticintdistCandyUtil(Noderoot,int[]ans){if(root==null)return0;// Traverse left subtreeintl=distCandyUtil(root.left,ans);// Traverse right subtreeintr=distCandyUtil(root.right,ans);ans[0]+=Math.abs(l)+Math.abs(r);// Return number of moves to balance// current nodereturnroot.data+l+r-1;}// Function to find the number of moves staticintdistCandy(Noderoot){int[]ans=newint[1];distCandyUtil(root,ans);returnans[0];}publicstaticvoidmain(String[]args){// Representation of given Binary Tree// 5// / \// 0 0// / \// 0 0Noderoot=newNode(5);root.left=newNode(0);root.right=newNode(0);root.right.left=newNode(0);root.right.right=newNode(0);System.out.println(distCandy(root));}}
Python
# Node StructureclassNode:def__init__(self,x):self.data=xself.left=Noneself.right=None# function to find the number of# moves to distribute all of the candiesdefdistCandyUtil(root,ans):ifrootisNone:return0# Traverse left subtreel=distCandyUtil(root.left,ans)# Traverse right subtreer=distCandyUtil(root.right,ans)ans[0]+=abs(l)+abs(r)# Return number of moves to balance# current nodereturnroot.data+l+r-1# Function to find the number of moves defdistCandy(root):ans=[0]distCandyUtil(root,ans)returnans[0]if__name__=="__main__":# Representation of given Binary Tree# 5# / \# 0 0# / \# 0 0root=Node(5)root.left=Node(0)root.right=Node(0)root.right.left=Node(0)root.right.right=Node(0)print(distCandy(root))
C#
usingSystem;// Node StructureclassNode{publicintdata;publicNodeleft,right;publicNode(intx){data=x;left=right=null;}}// function to find the number of// moves to distribute all of the candiesclassGFG{staticintdistCandyUtil(Noderoot,refintans){if(root==null)return0;// Traverse left subtreeintl=distCandyUtil(root.left,refans);// Traverse right subtreeintr=distCandyUtil(root.right,refans);ans+=Math.Abs(l)+Math.Abs(r);// Return number of moves to balance// current nodereturnroot.data+l+r-1;}// Function to find the number of moves staticintdistCandy(Noderoot){intans=0;distCandyUtil(root,refans);returnans;}staticvoidMain(string[]args){// Representation of given Binary Tree// 5// / \// 0 0// / \// 0 0Noderoot=newNode(5);root.left=newNode(0);root.right=newNode(0);root.right.left=newNode(0);root.right.right=newNode(0);Console.WriteLine(distCandy(root));}}
JavaScript
// Node StructureclassNode{constructor(x){this.data=x;this.left=null;this.right=null;}}// function to find the number of// moves to distribute all of the candiesfunctiondistCandyUtil(root,ans){if(root===null)return0;// Traverse left subtreeletl=distCandyUtil(root.left,ans);// Traverse right subtreeletr=distCandyUtil(root.right,ans);ans.moves+=Math.abs(l)+Math.abs(r);// Return number of moves to balance// current nodereturnroot.data+l+r-1;}// Function to find the number of moves functiondistCandy(root){letans={moves:0};distCandyUtil(root,ans);returnans.moves;}// Driver Code// Representation of given Binary Tree// 5// / \// 0 0// / \// 0 0letroot=newNode(5);root.left=newNode(0);root.right=newNode(0);root.right.left=newNode(0);root.right.right=newNode(0);console.log(distCandy(root));
Output
6
[Expected Approach - 2] Using Iteration - O(n) Time and O(n) Space
At each node, some candies will come from the left and goes to the right or vice versa. At each case, moves will increase. So, for each node we will count number of required candies in the right child and in left child i.e (total number of node - total candies) for each child. It is possible that it might be less than 0 but in that case too it will counted as move because extra candies also has to travel through the root node.
Steps:
We use a stack to traverse the tree in post-order without recursion.
Track each node’s state to ensure children are processed before the parent.
We use a map to store excess candies at each node: excess = nodeCandies + leftExcess + rightExcess - 1.
Count moves as abs(leftExcess) + abs(rightExcess).
Pass the node’s excess to its parent.
Repeat until the root is processed; total moves give the minimum required.
C++
#include<iostream>#include<stack>#include<unordered_map>usingnamespacestd;// Node StructureclassNode{public:intdata;Node*left;Node*right;Node(intx){data=x;left=right=nullptr;}};// Function to find the number of moves intdistCandy(Node*root){if(root==nullptr)return0;intans=0;stack<pair<Node*,int>>stk;unordered_map<Node*,int>balance;// Push root node into the stack // with state 0 (not processed)stk.push({root,0});while(!stk.empty()){// Get the top node and its state // from the stackautocurr=stk.top();autonode=curr.first;autostate=curr.second;stk.pop();if(node==nullptr)continue;// If state is 0, push node back with // state 1 (post-processing)if(state==0){// Push current node back with // state 1 for post-order processingstk.push({node,1});stk.push({node->left,0});stk.push({node->right,0});}else{intleftBalance=balance[node->left];intrightBalance=balance[node->right];// Add moves required for left and right subtreesans+=abs(leftBalance)+abs(rightBalance);// Calculate current node's balance: (candies - 1)balance[node]=node->data+leftBalance+rightBalance-1;}}returnans;}intmain(){// Representation of given Binary Tree// 5// / \// 0 0// / \// 0 0Node*root=newNode(5);root->left=newNode(0);root->right=newNode(0);root->right->left=newNode(0);root->right->right=newNode(0);cout<<distCandy(root);return0;}
Java
importjava.util.Stack;importjava.util.HashMap;// Node StructureclassNode{intdata;Nodeleft;Noderight;Node(intx){data=x;left=right=null;}}classPair<K,V>{privateKkey;privateVvalue;publicPair(Kkey,Vvalue){this.key=key;this.value=value;}// Method to get the keypublicKgetKey(){returnkey;}// Method to get the valuepublicVgetValue(){returnvalue;}// Method to set the keypublicvoidsetKey(Kkey){this.key=key;}// Method to set the valuepublicvoidsetValue(Vvalue){this.value=value;}}// Function to find the number of moves classGFG{staticintdistCandy(Noderoot){if(root==null)return0;intans=0;Stack<Pair<Node,Integer>>stk=newStack<>();HashMap<Node,Integer>balance=newHashMap<>();// Push root node into the stack // with state 0 (not processed)stk.push(newPair<>(root,0));while(!stk.isEmpty()){// Get the top node and its state // from the stackPair<Node,Integer>curr=stk.pop();Nodenode=curr.getKey();intstate=curr.getValue();if(node==null)continue;// If state is 0, push node back with // state 1 (post-processing)if(state==0){// Push current node back with // state 1 for post-order processingstk.push(newPair<>(node,1));stk.push(newPair<>(node.left,0));stk.push(newPair<>(node.right,0));}else{intleftBalance=balance.getOrDefault(node.left,0);intrightBalance=balance.getOrDefault(node.right,0);// Add moves required for left and right subtreesans+=Math.abs(leftBalance)+Math.abs(rightBalance);// Calculate current node's balance: (candies - 1)balance.put(node,node.data+leftBalance+rightBalance-1);}}returnans;}publicstaticvoidmain(String[]args){// Representation of given Binary Tree// 5// / \// 0 0// / \// 0 0Noderoot=newNode(5);root.left=newNode(0);root.right=newNode(0);root.right.left=newNode(0);root.right.right=newNode(0);System.out.println(distCandy(root));}}
Python
# Node StructureclassNode:def__init__(self,x):self.data=xself.left=Noneself.right=None# Function to find the number of moves defdistCandy(root):ifrootisNone:return0ans=0stk=[]# Dictionary to store balance of# candies at each nodebalance={}# Push root node into the stack # with state 0 (not processed)stk.append((root,0))whilestk:# Get the top node and its state # from the stackcurr=stk.pop()node=curr[0]state=curr[1]ifnodeisNone:continue# If state is 0, push node back with # state 1 (post-processing)ifstate==0:# Push current node back with # state 1 for post-order processingstk.append((node,1))stk.append((node.left,0))stk.append((node.right,0))else:leftBalance=balance.get(node.left,0)rightBalance=balance.get(node.right,0)# Add moves required for left and right subtreesans+=abs(leftBalance)+abs(rightBalance)# Calculate current node's balance: (candies - 1)balance[node]=node.data+leftBalance+rightBalance-1returnansif__name__=="__main__":# Representation of given Binary Tree# 5# / \# 0 0# / \# 0 0root=Node(5)root.left=Node(0)root.right=Node(0)root.right.left=Node(0)root.right.right=Node(0)print(distCandy(root))
C#
usingSystem;usingSystem.Collections.Generic;// Node StructureclassNode{publicintdata;publicNodeleft;publicNoderight;publicNode(intx){data=x;left=null;right=null;}}classGFG{// Function to find the number of moves staticintdistCandy(Noderoot){if(root==null)return0;intans=0;Stack<(Node,int)>stk=newStack<(Node,int)>();// Dictionary to store balance of // candies at each nodeDictionary<Node,int>balance=newDictionary<Node,int>();// Push root node into the stack // with state 0 (not processed)stk.Push((root,0));while(stk.Count>0){// Get the top node and its state // from the stackvarcurr=stk.Pop();varnode=curr.Item1;varstate=curr.Item2;if(node==null)continue;// If state is 0, push node back with // state 1 (post-processing)if(state==0){// Push current node back with // state 1 for post-order processingstk.Push((node,1));stk.Push((node.left,0));stk.Push((node.right,0));}else{intleftBalance=(node.left!=null&&balance.ContainsKey(node.left))?balance[node.left]:0;intrightBalance=(node.right!=null&&balance.ContainsKey(node.right))?balance[node.right]:0;// Add moves required for left and right subtreesans+=Math.Abs(leftBalance)+Math.Abs(rightBalance);// Calculate current node's balance: (candies - 1)balance[node]=node.data+leftBalance+rightBalance-1;}}returnans;}staticvoidMain(){// Representation of given Binary Tree// 5// / \// 0 0// / \// 0 0Noderoot=newNode(5);root.left=newNode(0);root.right=newNode(0);root.right.left=newNode(0);root.right.right=newNode(0);Console.WriteLine(distCandy(root));}}
JavaScript
// Node StructureclassNode{constructor(x){this.data=x;this.left=null;this.right=null;}}// Function to find the number of moves functiondistCandy(root){if(root===null)return0;letans=0;conststk=[];// Map to store balance of candies// at each nodeconstbalance=newMap();// Push root node into the stack // with state 0 (not processed)stk.push([root,0]);while(stk.length>0){// Get the top node and its state // from the stackconst[node,state]=stk.pop();if(node===null)continue;// If state is 0, push node back with // state 1 (post-processing)if(state===0){// Push current node back with // state 1 for post-order processingstk.push([node,1]);stk.push([node.left,0]);stk.push([node.right,0]);}else{constleftBalance=node.left&&balance.has(node.left)?balance.get(node.left):0;constrightBalance=node.right&&balance.has(node.right)?balance.get(node.right):0;// Add moves required for left and right subtreesans+=Math.abs(leftBalance)+Math.abs(rightBalance);// Calculate current node's balance: (candies - 1)balance.set(node,node.data+leftBalance+rightBalance-1);}}returnans;}// Driver Code// Representation of given Binary Tree// 5// / \// 0 0// / \// 0 0letroot=newNode(5);root.left=newNode(0);root.right=newNode(0);root.right.left=newNode(0);root.right.right=newNode(0);console.log(distCandy(root));