Open In App

Minimum number of additional Trees to have exactly n-leaf nodes

Improve
Improve
Like Article
Like
Save
Share
Report

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: 2

 

Input: 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++




// 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




// 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));
    }
}


Python




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#




// 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));
    }
}


Javascript




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));


Output

2

Time Complexity: O(logN)
Auxiliary Space: O(1)



Last Updated : 14 Apr, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads