Given a positive integer N, the task is to find the largest and smallest elements, from the maximum leaf nodes of every possible binary max-heap formed by taking the first N natural numbers as the nodes' value of the binary max-heap.
Examples:
Input: N = 2
Output: 1 1
Explanation:
There is only one maximum binary heap with the nodes {1, 2}:![]()
In the above tree, maximum leaf node value = 1.
Therefore, the largest element is 1 and the smallest element is also 1.Input: N = 3
Output: 2 2
Explanation:
There are two possible maximum binary heaps with the nodes {1, 2, 3}:![]()
The maximum leaf nodes of first and second heaps are 2 and 2 respectively.
Therefore, the largest element is 2 and the smallest element is also 2.
Naive Approach: The simplest approach is to generate all possible max binary heaps that can be formed from first N natural numbers and keep track of the smallest and largest leaf node values among all the maximum leaf nodes in all the heaps.
Time Complexity: O(N*N!)
Auxiliary Space: O(1)
Efficient Approach: The above approach can be optimized based on the following observations:
- The max heap is a complete binary tree, therefore, the height and count of the number of leaf nodes are fixed.
- In the max heap, the value of the node is always greater than or equal to the children of that node.
- The maximum leaf node value is always greater than or equal to the number of leaves in the tree. Therefore, the maximum value of a leaf node will be minimized if the smallest numbers are placed at the leaf nodes. And will be equal to the number of leaves node.
- One more property of the max heaps is as one will go down the tree the values of nodes decrease. Therefore, the maximum value of a node will be maximized if a number is placed at the leaf node with the least possible depth. So if D is the depth of that node then the maximum possible value of the node will be equal to the N-D.
- If D is the depth of the max Heap then the possible Depths of the leaf nodes are D and D-1 only, as the heaps are the complete binary tree.
- If V is a leaf node then (2*V) must be greater than N. Therefore, the count of leaf nodes is equal to the, (N - N/2).
Follow the steps below to solve the problem:
- Calculate the count of leaf nodes in the max heap of N nodes, as discussed above, and store it in a variable say numberOfleaves.
numberOfleaves = (N- N/2).
- Find the depth of the max heap and store it in a variable say D.
D = ceil(log2(N+1))-1
- If N+1 is not a power of 2 and D is greater than 1, then there must exit a leaf node at depth D-1. Therefore, then decrement D by 1.
- Finally, after completing the above steps, print the largest value as (N-D) and the smallest value as numberOfleaves.
Below is the implementation of the above approach:
// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
// Function to find largest and smallest
// elements from the maximum leaf nodes
// values from all possible binary max heap
void leafNodeValues(int N)
{
// Stores count of leaf nodes
int numberOfLeaves = (N - N / 2);
// Stores minDepth with N
int minDepth = ceil(log2(N + 1)) - 1;
// Increment N by 1
N++;
// If N is not power of 2 and minDepth
// is greater than 1
if (minDepth > 1 && (N & (N - 1)))
minDepth--;
// Print the smallest and largest possible
// value of a leaf node
cout << numberOfLeaves << ' '
<< N - minDepth - 1;
}
// Driver Code
int main()
{
// Given Input
int N = 2;
// Function Call
leafNodeValues(N);
return 0;
}
// Java program for the above approach
class GFG{
// Function to find largest and smallest
// elements from the maximum leaf nodes
// values from all possible binary max heap
static void leafNodeValues(int N)
{
// Stores count of leaf nodes
int numberOfLeaves = (N - N / 2);
// Stores minDepth with N
int minDepth = (int)Math.ceil(Math.log(N + 1) /
Math.log(2)) - 1;
// Increment N by 1
N++;
// If N is not power of 2 and minDepth
// is greater than 1
if (minDepth > 1 && (N & (N - 1)) != 0)
minDepth--;
// Print the smallest and largest possible
// value of a leaf node
System.out.println(numberOfLeaves + " " +
(N - minDepth - 1));
}
// Driver code
public static void main(String[] args)
{
// Given Input
int N = 2;
// Function Call
leafNodeValues(N);
}
}
// This code is contributed by divyesh072019
# Python 3 program for the above approach
from math import ceil,log2
# Function to find largest and smallest
# elements from the maximum leaf nodes
# values from all possible binary max heap
def leafNodeValues(N):
# Stores count of leaf nodes
numberOfLeaves = (N - N // 2)
# Stores minDepth with N
minDepth = ceil(log2(N + 1)) - 1;
# Increment N by 1
N += 1
# If N is not power of 2 and minDepth
# is greater than 1
if (minDepth > 1 and (N & (N - 1))):
minDepth -= 1
# Print the smallest and largest possible
# value of a leaf node
print(numberOfLeaves, N - minDepth - 1)
# Driver Code
if __name__ == '__main__':
# Given Input
N = 2
# Function Call
leafNodeValues(N)
# This code is contributed by SURENDRA_GANGWAR.
// C# program for the above approach
using System;
class GFG {
// Function to find largest and smallest
// elements from the maximum leaf nodes
// values from all possible binary max heap
static void leafNodeValues(int N)
{
// Stores count of leaf nodes
int numberOfLeaves = (N - N / 2);
// Stores minDepth with N
int minDepth = (int)Math.Ceiling(Math.Log(N + 1) /
Math.Log(2)) - 1;
// Increment N by 1
N++;
// If N is not power of 2 and minDepth
// is greater than 1
if (minDepth > 1 && (N & (N - 1)) != 0)
minDepth--;
// Print the smallest and largest possible
// value of a leaf node
Console.WriteLine(numberOfLeaves + " " +
(N - minDepth - 1));
}
static void Main()
{
// Given Input
int N = 2;
// Function Call
leafNodeValues(N);
}
}
// This code is contributed by decode2207.
<script>
// JavaScript program for the above approach
// Function to find largest and smallest
// elements from the maximum leaf nodes
// values from all possible binary max heap
function log2(n)
{
return (Math.log(n)/Math.log(2));
}
function leafNodeValues(N)
{
// Stores count of leaf nodes
let numberOfLeaves = parseInt((N - N / 2));
// Stores minDepth with N
let minDepth = Math.ceil(log2(N + 1)) - 1;
// Increment N by 1
N++;
// If N is not power of 2 and minDepth
// is greater than 1
if ((minDepth > 1) && (N & (N - 1)))
minDepth--;
// Print the smallest and largest possible
// value of a leaf node
document.write(numberOfLeaves);
document.write(' ');
document.write( N - minDepth - 1);
}
// Driver Code
// Given Input
var N = 2;
// Function Call
leafNodeValues(N);
// This code is contributed by Potta Lokesh
</script>
Output:
1 1
Time Complexity: O(log(N))
Auxiliary Space: O(1)
