Count leaf nodes in a perfect n-ary tree of height m. A perfect n-ary tree is a specialized hierarchical data structure where every internal node has exactly n children, and all leaf nodes exist at the exact same depth.
Note: Return the answer modulo 109+7.
Examples:
Input: n = 2, m = 2
Output: 4
Explanation: A full Binary tree of height 2 has 4 leaf nodes.Input: n = 2, m = 1
Output: 2
Explanation: A full Binary tree of height 1 has 2 leaf nodes.
Table of Content
[Naive Approach] Iterative Multiplication - O(m) Time and O(1) Space
The idea is to observe that the number of leaf nodes in a perfect n-ary tree of height m is n^m. So, multiply n exactly m times and take modulo 10^9 + 7 after every multiplication to keep the result within range.
Working of Approach:
- Initialize the answer as 1 because n^0 = 1.
- Multiply the current answer by n exactly m times.
- Take modulo 10^9 + 7 after every multiplication to prevent overflow.
- After m multiplications, the result becomes n^m, which is the number of leaf nodes.
#include <bits/stdc++.h>
using namespace std;
int karyTree(int n, int m)
{
const int MOD = 1000000007;
// Initialize result
int res = 1;
// Multiply n exactly m times
for (int i = 0; i < m; i++)
res = (res * 1LL * n) % MOD;
return res;
}
int main()
{
int n = 2, m = 1;
cout << karyTree(n, m) << endl;
return 0;
}
import java.util.*;
public class GFG {
int karyTree(int n, int m)
{
final int MOD = 1000000007;
// Initialize result
int res = 1;
// Multiply n exactly m times
for (int i = 0; i < m; i++)
res = (int)((res * 1L * n) % MOD);
return res;
}
public static void main(String[] args)
{
GFG main = new GFG();
int n = 2, m = 1;
System.out.println(main.karyTree(n, m));
}
}
def karyTree(n, m):
MOD = 1000000007
# Initialize result
res = 1
# Multiply n exactly m times
for i in range(m):
res = (res * n) % MOD
return res
if __name__ == '__main__':
n = 2
m = 1
print(karyTree(n, m))
using System;
public class GFG {
public int karyTree(int n, int m)
{
const int MOD = 1000000007;
// Initialize result
int res = 1;
// Multiply n exactly m times
for (int i = 0; i < m; i++)
res = (int)((res * 1L * n) % MOD);
return res;
}
public static void Main()
{
GFG program = new GFG();
int n = 2, m = 1;
Console.WriteLine(program.karyTree(n, m));
}
}
function karyTree(n, m)
{
const MOD = 1000000007;
// Initialize result
let res = 1;
// Multiply n exactly m times
for (let i = 0; i < m; i++) {
res = (res * n) % MOD;
}
return res;
}
// Driver Code
let n = 2, m = 1;
console.log(karyTree(n, m));
Output
2
[Expected Approach] Binary Exponentiation - O(log m) Time and O(1) Space
The idea is to compute n^m using binary exponentiation. Instead of multiplying n repeatedly m times, square the base and process the exponent bit by bit, reducing the number of multiplications from O(m) to O(log m) while taking modulo 10^9 + 7 at every step.
Working of Approach:
- Initialize the result as 1 and repeatedly process the exponent m until it becomes 0.
- If the current bit of the exponent is 1, multiply the current base with the result.
- Square the base and divide the exponent by 2 in each iteration.
- The final result is n^m modulo 10^9 + 7, which is the number of leaf nodes.
Let us understand with an example:
Input: n = 2, m = 1
- Initialize res = 1, base = 2, and exponent = 1.
- Since the exponent is odd, update res = (1 × 2) = 2.
- Square the base: base = 2 × 2 = 4, and divide the exponent by 2, so exponent = 0.
- The exponent becomes 0, so stop. The final answer is 2, which is the number of leaf nodes.
#include <bits/stdc++.h>
using namespace std;
int power(int x, int y, int p)
{
// Initialize result
int res = 1;
// Update x if it is more than or equal to p
x = x % p;
// In case x is divisible by p;
if (x == 0)
return 0;
while (y > 0)
{
// If y is odd, multiply x with result
if (y & 1)
res = (res * 1LL * x) % p;
// y must be even now
y = y >> 1; // y = y/2
x = (x * 1LL * x) % p;
}
return res;
}
int karyTree(int n, int m)
{
int p = 1000000007;
int ans = power((int)n, (int)m, p);
return ans;
}
int main()
{
int n = 2, m = 1;
cout << karyTree(n, m) << endl;
return 0;
}
import java.io.*;
class GFG {
static int power(int x, int y, int p)
{
// Initialize result
int res = 1;
// Update x if it is more than or equal to p
x = x % p;
// In case x is divisible by p
if (x == 0)
return 0;
while (y > 0) {
// If y is odd, multiply x with result
if ((y & 1) == 1)
res = (int)((res * 1L * x) % p);
// y must be even now
y = y >> 1;
x = (int)((x * 1L * x) % p);
}
return res;
}
static int karyTree(int n, int m)
{
int p = 1000000007;
int ans = power(n, m, p);
return ans;
}
public static void main(String[] args)
{
int n = 2, m = 1;
System.out.println(karyTree(n, m));
}
}
def power(x, y, p):
# Initialize result
res = 1
# Update x if it is more than or equal to p
x %= p
# In case x is divisible by p
if x == 0:
return 0
while y > 0:
# If y is odd, multiply x with result
if y & 1:
res = (res * x) % p
# y must be even now
y >>= 1
x = (x * x) % p
return res
def karyTree(n, m):
p = 1000000007
ans = power(n, m, p)
return ans
if __name__ == "__main__":
n, m = 2, 1
print(karyTree(n, m))
using System;
class GFG {
static int Power(int x, int y, int p)
{
// Initialize result
int res = 1;
// Update x if it is more than or equal to p
x = x % p;
// In case x is divisible by p
if (x == 0)
return 0;
while (y > 0) {
// If y is odd, multiply x with result
if ((y & 1) == 1)
res = (int)((res * 1L * x) % p);
// y must be even now
y >>= 1;
x = (int)((x * 1L * x) % p);
}
return res;
}
static int karyTree(int n, int m)
{
int p = 1000000007;
int ans = Power(n, m, p);
return ans;
}
static void Main()
{
int n = 2, m = 1;
Console.WriteLine(karyTree(n, m));
}
}
function power(x, y, p)
{
// Initialize result
let res = 1n;
// Convert to BigInt
x = BigInt(x);
y = BigInt(y);
p = BigInt(p);
// Update x if it is more than or equal to p
x = x % p;
// In case x is divisible by p
if (x == 0n)
return 0;
while (y > 0n) {
// If y is odd, multiply x with result
if (y & 1n)
res = (res * x) % p;
// y must be even now
y = y >> 1n; // y = y/2
x = (x * x) % p;
}
return Number(res);
}
function karyTree(n, m)
{
let p = 1000000007;
let ans = power(n, m, p);
return ans;
}
//Driver Code
let n = 2, m = 1;
console.log(karyTree(n, m));
Output
2