Given a tree with only one node. We want a tree with exactly n-leaf nodes. We have exactly k trees consisting of 1, 2, …, and k leaf nodes. For example, we had k additional trees. The only operation we can do now is to superimpose the root of one of the additional trees onto any leave of the original tree. Determine the minimum number of additional trees to have exactly n-leaf nodes if it is impossible by returning -1.
Note: Superimpose means we can attach the root of the additional tree with any of the leaves of the original tree.
Examples:
Input: n = 4, k = 3
Output: 2Input: n = 4, k = 2
Output: -1
Approach: This can be solved with the following idea:
Using binary search, we can find a minimum number of trees to be added to have exactly n-leaf nodes.
Steps involved in the implementation of code:
- Whenever we have to find minimal we can think of a binary search.
- Now, we can go from 1 to k nodes and find the mid in such a way that we can generate the n-leaf nodes. If we are able to find the n leaf node we can do mid-1 and find whether it is possible for lower values[1..(mid-1)] or not.
- Otherwise, we will do mid+1 if we are not able to find the n-leaf nodes.
- Now we can check whether mid is valid or not with the help of the find(int mid, int k) function.
- find(int mid, int k) :
- A total number of leaf nodes temp= k-mid+1, which means this much amount of leaf nodes are always present.
- Then those temp nodes are part of the new additional tree’s leaf nodes which we can find with the help of the findSum(temp, k-1) function.
- This function returns the count of the total number of leaf nodes.
-
findSum(temp, k-1):
- Here we already utilized one tree that’s why we are passing k-1 as an argument.
- Now, to get the additional trees’ leaf node sum we can say low = temp and high = k – 1 and we can return the difference between the sum of the two trees that we have added.[ For Example: If we added two trees with 4 and 6 leaf nodes, we can return the sum(1..6)-sum(1..3) of leaf nodes to get the total number of leaf nodes.]
Below is the Implementation of the code:
// C++ code of the above approach #include <bits/stdc++.h> #include <iostream> using namespace std;
// Function to find currently how many // leaf nodes are there long long findSum( int low, int high)
{ if (low > high)
return 0;
low--;
long s1 = (low * 1ll * (low + 1)) / 2;
long s2 = (high * 1ll * (high + 1)) / 2;
return s2 - s1;
} // Find total leaf nodes long long find( int mid, int k)
{ int temp = k - mid + 1;
long sum = temp;
sum += findSum(temp, k - 1);
return sum;
} // Binary search to find minimum trees // required int impressGeekina( long long n, int k)
{ if (n == 1) {
return 0;
}
int low = 1, high = k;
while (low <= high) {
int mid = (low + high) / 2;
long pos = find(mid, k);
if (pos >= n)
high = mid - 1;
else
low = mid + 1;
}
if (low > k)
return -1;
return low;
} // Driver code int main()
{ int n = 4;
int k = 3;
// Function call
cout << impressGeekina(n, k);
return 0;
} |
// Java code of the above approach import java.util.*;
class GFG {
// Function to find currently how many
// leaf nodes are there
public static long findSum( int low, int high)
{
if (low > high)
return 0 ;
low--;
long s1 = (low * 1L * (low + 1 )) / 2 ;
long s2 = (high * 1L * (high + 1 )) / 2 ;
return s2 - s1;
}
// Find total leaf nodes
public static long find( int mid, int k)
{
int temp = k - mid + 1 ;
long sum = temp;
sum += findSum(temp, k - 1 );
return sum;
}
// Binary search to find minimum trees
// required
public static int impressGeekina( long n, int k)
{
if (n == 1 ) {
return 0 ;
}
int low = 1 , high = k;
while (low <= high) {
int mid = (low + high) / 2 ;
long pos = find(mid, k);
if (pos >= n)
high = mid - 1 ;
else
low = mid + 1 ;
}
if (low > k)
return - 1 ;
return low;
}
// Driver code
public static void main(String[] args)
{
int n = 4 ;
int k = 3 ;
// Function call
System.out.println(impressGeekina(n, k));
}
} |
def find_sum(low, high):
if low > high:
return 0
low - = 1
s1 = (low * (low + 1 )) / / 2
s2 = (high * (high + 1 )) / / 2
return s2 - s1
def find(mid, k):
temp = k - mid + 1
sum_ = temp
sum_ + = find_sum(temp, k - 1 )
return sum_
def impress_geekina(n, k):
if n = = 1 :
return 0
low, high = 1 , k
while low < = high:
mid = (low + high) / / 2
pos = find(mid, k)
if pos > = n:
high = mid - 1
else :
low = mid + 1
if low > k:
return - 1
return low
n = 4
k = 3
print (impress_geekina(n, k))
|
// C# code of the above approach using System;
using System.Linq;
using System.Collections.Generic;
class Gfg{
// Function to find currently how many
// leaf nodes are there
static long findSum( int low, int high)
{
if (low > high)
return 0;
low--;
long s1 = (low * 1 * (low + 1)) / 2;
long s2 = (high * 1 * (high + 1)) / 2;
return s2 - s1;
}
// Find total leaf nodes
static long find( int mid, int k)
{
int temp = k - mid + 1;
long sum = temp;
sum += findSum(temp, k - 1);
return sum;
}
// Binary search to find minimum trees
// required
static int impressGeekina( long n, int k)
{
if (n == 1) {
return 0;
}
int low = 1, high = k;
while (low <= high) {
int mid = (low + high) / 2;
long pos = find(mid, k);
if (pos >= n)
high = mid - 1;
else
low = mid + 1;
}
if (low > k)
return -1;
return low;
}
// Driver code
public static void Main( string [] args)
{
int n = 4;
int k = 3;
// Function call
Console.Write(impressGeekina(n, k));
}
} |
function findSum(low, high) {
if (low > high) return 0;
low--;
let s1 = (low * (low + 1)) / 2;
let s2 = (high * (high + 1)) / 2;
return s2 - s1;
} function find(mid, k) {
let temp = k - mid + 1;
let sum = temp;
sum += findSum(temp, k - 1);
return sum;
} function impressGeekina(n, k) {
if (n == 1) {
return 0;
}
let low = 1, high = k;
while (low <= high) {
let mid = Math.floor((low + high) / 2);
let pos = find(mid, k);
if (pos >= n) high = mid - 1;
else low = mid + 1;
}
if (low > k) return -1;
return low;
} // Driver code let n = 4; let k = 3; // Function call console.log(impressGeekina(n, k)); |
2
Time Complexity: O(logN)
Auxiliary Space: O(1)