Distribute candies in a Binary Tree
Given a binary tree with N nodes, in which each node value represents the number of candies present at that node, and there are N candies in total. In one move, one may choose two adjacent nodes and move one candy from one node to another (the move may be from parent to child, or from child to parent.)
The task is to find the number of moves required such that every node has exactly one candy.
Examples:
Input : 3
/ \
0 0
Output : 2
Explanation: From the root of the tree, we move one
candy to its left child, and one candy to
its right child.
Input : 0
/ \
3 0
Output :3
Explanation : From the left child of the root, we move
two candies to the root [taking two moves]. Then, we move
one candy from the root of the tree to the right child.
Recursive Solution:
The idea is 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 (an excess of -1 from what it needs), then we should push a candy from its parent onto the node.
- If the node has more than 1 candy. If it has say, 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(num_candies – 1).
Once a node is balanced, we never have to consider this node again in the rest of our calculation.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
struct Node {
int key;
struct Node *left, *right;
};
Node* newNode( int key)
{
Node* temp = new Node;
temp->key = key;
temp->left = temp->right = NULL;
return (temp);
}
int distributeCandyUtil(Node* root, int & ans)
{
if (root == NULL)
return 0;
int l = distributeCandyUtil(root->left, ans);
int r = distributeCandyUtil(root->right, ans);
ans += abs (l) + abs (r);
return root->key + l + r - 1;
}
int distributeCandy(Node* root)
{
int ans = 0;
distributeCandyUtil(root, ans);
return ans;
}
int main()
{
Node* root = newNode(3);
root->left = newNode(0);
root->right = newNode(0);
cout << distributeCandy(root);
return 0;
}
|
Java
class GfG {
static class Node {
int key;
Node left, right;
}
static int ans = 0 ;
static Node newNode( int key)
{
Node temp = new Node();
temp.key = key;
temp.left = null ;
temp.right = null ;
return (temp);
}
static int distributeCandyUtil(Node root)
{
if (root == null )
return 0 ;
int l = distributeCandyUtil(root.left);
int r = distributeCandyUtil(root.right);
ans += Math.abs(l) + Math.abs(r);
return root.key + l + r - 1 ;
}
static int distributeCandy(Node root)
{
distributeCandyUtil(root);
return ans;
}
public static void main(String[] args)
{
Node root = newNode( 3 );
root.left = newNode( 0 );
root.right = newNode( 0 );
System.out.println(distributeCandy(root));
}
}
|
Python3
class Node:
def __init__( self , key):
self .key = key
self .left = None
self .right = None
def newNode(key):
temp = Node(key)
return temp
def distributeCandyUtil( root, ans):
if (root = = None ):
return 0 , ans;
l,ans = distributeCandyUtil(root.left, ans);
r,ans = distributeCandyUtil(root.right, ans);
ans + = abs (l) + abs (r);
return root.key + l + r - 1 , ans;
def distributeCandy(root):
ans = 0 ;
tmp, ans = distributeCandyUtil(root, ans);
return ans;
if __name__ = = '__main__' :
root = newNode( 3 );
root.left = newNode( 0 );
root.right = newNode( 0 );
print (distributeCandy(root))
|
C#
using System;
class GFG {
public class Node {
public int key;
public Node left, right;
}
static int ans = 0;
static Node newNode( int key)
{
Node temp = new Node();
temp.key = key;
temp.left = null ;
temp.right = null ;
return (temp);
}
static int distributeCandyUtil(Node root)
{
if (root == null )
return 0;
int l = distributeCandyUtil(root.left);
int r = distributeCandyUtil(root.right);
ans += Math.Abs(l) + Math.Abs(r);
return root.key + l + r - 1;
}
static int distributeCandy(Node root)
{
distributeCandyUtil(root);
return ans;
}
public static void Main(String[] args)
{
Node root = newNode(3);
root.left = newNode(0);
root.right = newNode(0);
Console.WriteLine(distributeCandy(root));
}
}
|
Javascript
<script>
class Node
{
constructor(key) {
this .left = null ;
this .right = null ;
this .key = key;
}
}
let ans = 0;
function newNode(key)
{
let temp = new Node(key);
return (temp);
}
function distributeCandyUtil(root)
{
if (root == null )
return 0;
let l = distributeCandyUtil(root.left);
let r = distributeCandyUtil(root.right);
ans += Math.abs(l) + Math.abs(r);
return root.key + l + r - 1;
}
function distributeCandy(root)
{
distributeCandyUtil(root);
return ans;
}
let root = newNode(3);
root.left = newNode(0);
root.right = newNode(0);
document.write(distributeCandy(root));
</script>
|
Time Complexity: O(n) where n is the number of nodes in given Binary Tree.
Auxiliary Space: O(h) where h is the height of given Binary Tree due to Recursion
Iterative Solution:
Approach: At each node, some candies will come from the left and goes to the right or comes from the right and goes to left. 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.
Below is the implementation of the iterative approach:
C++
#include <bits/stdc++.h>
using namespace std;
struct Node {
int key;
struct Node *left, *right;
};
Node* newNode( int key)
{
Node* temp = new Node;
temp->key = key;
temp->left = temp->right = NULL;
return (temp);
}
int countinchild(Node* root)
{
if (root == NULL)
return 0;
int numberofnodes = 0;
int sum = 0;
queue<Node*> q;
q.push(root);
while (q.size() != 0) {
Node* f = q.front();
q.pop();
numberofnodes++;
sum += f->key;
if (f->left)
q.push(f->left);
if (f->right)
q.push(f->right);
}
return abs (numberofnodes - sum);
}
int distributeCandy(Node* root)
{
int moves = 0;
if (root == NULL)
return 0;
if (!root->left && !root->right)
return 0;
queue<Node*> q;
q.push(root);
while (q.size() != 0) {
Node* f = q.front();
q.pop();
moves += countinchild(f->left);
moves += countinchild(f->right);
if (f->left)
q.push(f->left);
if (f->right)
q.push(f->right);
}
return moves;
}
int main()
{
Node* root = newNode(1);
root->left = newNode(0);
root->right = newNode(2);
cout << distributeCandy(root);
return 0;
}
|
Java
import java.util.*;
public class GFG
{
static class Node {
int key;
Node left, right;
Node( int item)
{
key = item;
left = right = null ;
}
}
static Node root;
public GFG()
{
root = null ;
}
static Node newNode( int key)
{
Node temp = new Node(key);
return (temp);
}
static int countinchild(Node root)
{
if (root == null )
return 0 ;
int numberofnodes = 0 ;
int sum = 0 ;
Queue<Node> q = new LinkedList<>();
q.add(root);
while (q.size() != 0 ) {
Node f = (Node)q.peek();
q.remove();
numberofnodes++;
sum += f.key;
if (f.left != null )
q.add(f.left);
if (f.right != null )
q.add(f.right);
}
return Math.abs(numberofnodes - sum);
}
static int distributeCandy(Node root)
{
int moves = 0 ;
if (root == null )
return 0 ;
if (root.left == null && root.right == null )
return 0 ;
Queue<Node> q = new LinkedList<>();
q.add(root);
while (q.size() != 0 ) {
Node f = (Node)q.peek();
q.remove();
moves += countinchild(f.left);
moves += countinchild(f.right);
if (f.left != null )
q.add(f.left);
if (f.right != null )
q.add(f.right);
}
return moves;
}
public static void main(String[] args) {
GFG tree = new GFG();
tree.root = newNode( 1 );
tree.root.left = newNode( 0 );
tree.root.right = newNode( 2 );
System.out.println(distributeCandy(tree.root));
}
}
|
Python3
class Node:
def __init__( self , key):
self .key = key
self .left = None
self .right = None
def newNode(key):
temp = Node(key)
return temp
def countinchild(root):
if (root = = None ):
return 0 ;
numberofnodes = 0 ;
sum = 0 ;
q = []
q.append(root);
while ( len (q) ! = 0 ):
f = q[ 0 ];
q.pop( 0 );
numberofnodes + = 1
sum + = f.key;
if (f.left):
q.append(f.left);
if (f.right):
q.append(f.right);
return abs (numberofnodes - sum );
def distributeCandy(root):
moves = 0 ;
if (root = = None ):
return 0 ;
if ( not root.left and not root.right):
return 0 ;
q = []
q.append(root);
while ( len (q) ! = 0 ):
f = q[ 0 ];
q.pop( 0 );
moves + = countinchild(f.left);
moves + = countinchild(f.right);
if (f.left):
q.append(f.left);
if (f.right):
q.append(f.right);
return moves;
if __name__ = = '__main__' :
root = newNode( 1 );
root.left = newNode( 0 );
root.right = newNode( 2 );
print (distributeCandy(root))
|
C#
using System;
using System.Collections;
using System.Collections.Generic;
class Node {
public int key;
public Node left, right;
public Node( int item)
{
key = item;
left = right = null ;
}
}
public class GFG {
Node root;
public GFG()
{
root = null ;
}
static Node newNode( int key)
{
Node temp = new Node(key);
return (temp);
}
static int countinchild(Node root)
{
if (root == null )
return 0;
int numberofnodes = 0;
int sum = 0;
Queue q = new Queue();
q.Enqueue(root);
while (q.Count != 0) {
Node f = (Node)q.Peek();
q.Dequeue();
numberofnodes++;
sum += f.key;
if (f.left != null )
q.Enqueue(f.left);
if (f.right != null )
q.Enqueue(f.right);
}
return Math.Abs(numberofnodes - sum);
}
static int distributeCandy(Node root)
{
int moves = 0;
if (root == null )
return 0;
if (root.left == null && root.right == null )
return 0;
Queue q = new Queue();
q.Enqueue(root);
while (q.Count != 0) {
Node f = (Node)q.Peek();
q.Dequeue();
moves += countinchild(f.left);
moves += countinchild(f.right);
if (f.left != null )
q.Enqueue(f.left);
if (f.right != null )
q.Enqueue(f.right);
}
return moves;
}
static void Main() {
GFG tree = new GFG();
tree.root = newNode(1);
tree.root.left = newNode(0);
tree.root.right = newNode(2);
Console.Write(distributeCandy(tree.root));
}
}
|
Javascript
<script>
class Node
{
constructor(key) {
this .left = null ;
this .right = null ;
this .key = key;
}
}
function newNode(key)
{
let temp = new Node(key);
return (temp);
}
function countinchild(root)
{
if (root == null )
return 0;
let numberofnodes = 0;
let sum = 0;
let q = [];
q.push(root);
while (q.length != 0) {
let f = q[0];
q.shift();
numberofnodes++;
sum += f.key;
if (f.left)
q.push(f.left);
if (f.right)
q.push(f.right);
}
return Math.abs(numberofnodes - sum);
}
function distributeCandy(root)
{
let moves = 0;
if (root == null )
return 0;
if (root.left == null && root.right == null )
return 0;
let q = [];
q.push(root);
while (q.length != 0) {
let f = q[0];
q.shift();
moves += countinchild(f.left);
moves += countinchild(f.right);
if (f.left)
q.push(f.left);
if (f.right)
q.push(f.right);
}
return moves;
}
let root = newNode(1);
root.left = newNode(0);
root.right = newNode(2);
document.write(distributeCandy(root));
</script>
|
Complexity Analysis:
- Time Complexity: O(N*N)
- Auxiliary Space: O(N)
Last Updated :
12 Jan, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...