Open In App

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

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:

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

Output
2

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


Article Tags :