Prime Numbers present at Kth level of a Binary Tree
Given a number K, the task is to print the prime numbers present at that level given all the prime numbers are represented in the form of a binary tree.
Examples:
Input: K = 3
2
/ \
3 5
/\ / \
7 11 13 17
Output :7, 11, 13, 17
Explanation:
2
/ \
3 5
/\ / \
7 11 13 17
So primes present at level 3 : 7, 11, 13, 17
Input :K = 2
2
/ \
3 5
Output :3 5
Naive Approach: The naive approach is to build a binary tree of prime numbers and then get elements at a particular level k.
It doesn’t work well for large numbers as it takes too much time.
Efficient approach: Suppose there are n elements and the task is to build a binary tree using those n elements, then they can be built using log2n levels.
Therefore, given a level k, elements present here is from 2k-1 to 2k-1 if all the prime numbers are present in a 1D array.
Hence, the following is the algorithm:
- Find the prime numbers upto MAX_SIZE using Sieve of Eratosthenes.
- Calculate the left_index and right_index of the level as left_index = 2k-1, right_index = 2k-1.
- Output primes from left_index to right_index of prime array.
C++
#include <bits/stdc++.h>
using namespace std;
#define MAX_SIZE 1000005
vector< int > primes;
void SieveOfEratosthenes(vector< int >& primes)
{
bool IsPrime[MAX_SIZE];
memset (IsPrime, true , sizeof (IsPrime));
for ( int p = 2; p * p < MAX_SIZE; p++) {
if (IsPrime[p] == true ) {
for ( int i = p * p; i < MAX_SIZE; i += p)
IsPrime[i] = false ;
}
}
for ( int p = 2; p < MAX_SIZE; p++)
if (IsPrime[p])
primes.push_back(p);
}
void printLevel( int level)
{
cout << "primes at level " << level << ": " ;
int left_index = pow (2, level - 1);
int right_index = pow (2, level) - 1;
for ( int i = left_index; i <= right_index; i++) {
cout << primes[i - 1] << " " ;
}
cout << endl;
}
int main()
{
SieveOfEratosthenes(primes);
printLevel(1);
printLevel(2);
printLevel(3);
printLevel(4);
return 0;
}
|
Java
import java.util.*;
class GFG
{
static final int MAX_SIZE = 1000005 ;
static Vector<Integer> primes = new Vector<Integer>();
static void SieveOfEratosthenes(Vector<Integer> primes)
{
boolean [] IsPrime = new boolean [MAX_SIZE];
for ( int i = 0 ; i < MAX_SIZE; i++)
IsPrime[i] = true ;
for ( int p = 2 ; p * p < MAX_SIZE; p++)
{
if (IsPrime[p] == true )
{
for ( int i = p * p; i < MAX_SIZE; i += p)
IsPrime[i] = false ;
}
}
for ( int p = 2 ; p < MAX_SIZE; p++)
if (IsPrime[p])
primes.add(p);
}
static void printLevel( int level)
{
System.out.print( "primes at level " + level + ": " );
int left_index = ( int ) Math.pow( 2 , level - 1 );
int right_index = ( int ) (Math.pow( 2 , level) - 1 );
for ( int i = left_index; i <= right_index; i++)
{
System.out.print(primes.get(i - 1 ) + " " );
}
System.out.println();
}
public static void main(String[] args)
{
SieveOfEratosthenes(primes);
printLevel( 1 );
printLevel( 2 );
printLevel( 3 );
printLevel( 4 );
}
}
|
Python3
MAX_SIZE = 1000005
primes = []
def SieveOfEratosthenes():
IsPrime = [ True ] * MAX_SIZE
p = 2
while p * p < MAX_SIZE:
if (IsPrime[p] = = True ):
for i in range (p * p, MAX_SIZE, p):
IsPrime[i] = False
p + = 1
for p in range ( 2 , MAX_SIZE):
if (IsPrime[p]):
primes.append(p)
def printLevel(level):
print ( "primes at level " , level, ":" , end = " " )
left_index = pow ( 2 , level - 1 )
right_index = pow ( 2 , level) - 1
for i in range (left_index, right_index + 1 ):
print (primes[i - 1 ], end = " " )
print ()
SieveOfEratosthenes()
printLevel( 1 )
printLevel( 2 )
printLevel( 3 )
printLevel( 4 )
|
C#
using System;
using System.Collections.Generic;
class GFG
{
static readonly int MAX_SIZE = 1000005;
static List< int > primes = new List< int >();
static void SieveOfEratosthenes(List< int > primes)
{
bool [] IsPrime = new bool [MAX_SIZE];
for ( int i = 0; i < MAX_SIZE; i++)
IsPrime[i] = true ;
for ( int p = 2; p * p < MAX_SIZE; p++)
{
if (IsPrime[p] == true )
{
for ( int i = p * p; i < MAX_SIZE; i += p)
IsPrime[i] = false ;
}
}
for ( int p = 2; p < MAX_SIZE; p++)
if (IsPrime[p])
primes.Add(p);
}
static void printLevel( int level)
{
Console.Write( "primes at level " + level + ": " );
int left_index = ( int ) Math.Pow(2, level - 1);
int right_index = ( int ) (Math.Pow(2, level) - 1);
for ( int i = left_index; i <= right_index; i++)
{
Console.Write(primes[i - 1] + " " );
}
Console.WriteLine();
}
public static void Main(String[] args)
{
SieveOfEratosthenes(primes);
printLevel(1);
printLevel(2);
printLevel(3);
printLevel(4);
}
}
|
Javascript
<script>
let MAX_SIZE = 1000005
let primes = new Array();
function SieveOfEratosthenes(primes)
{
let IsPrime = new Array(MAX_SIZE).fill( true );
for (let p = 2; p * p < MAX_SIZE; p++)
{
if (IsPrime[p] == true )
{
for (let i = p * p; i < MAX_SIZE; i += p)
IsPrime[i] = false ;
}
}
for (let p = 2; p < MAX_SIZE; p++)
if (IsPrime[p])
primes.push(p);
}
function printLevel(level)
{
document.write( "primes at level " +
level + ": " );
let left_index = Math.pow(2, level - 1);
let right_index = Math.pow(2, level) - 1;
for (let i = left_index; i <= right_index; i++)
{
document.write(primes[i - 1] + " " );
}
document.write( "<br>" );
}
SieveOfEratosthenes(primes);
printLevel(1);
printLevel(2);
printLevel(3);
printLevel(4);
</script>
|
Output
primes at level 1: 2
primes at level 2: 3 5
primes at level 3: 7 11 13 17
primes at level 4: 19 23 29 31 37 41 43 47
Approach: Breadth First Search
Approach Steps:
- uses a queue data structure to keep track of nodes at each level and checks each dequeued node for primality.
- If a node is prime and at the desired level, it is added to a list of prime numbers at that level.
- After all nodes at the current level have been processed, the list of prime numbers is printed in the desired format and variables are updated to process the next level.
- Last ensures that nodes at each level are processed before moving on to the next level.
- and the queue ensures that nodes are processed in the order in which they appear at each level.
Below is the code implementation:
C++
#include <cmath>
#include <iostream>
#include <queue>
struct Node {
int val;
Node* left;
Node* right;
Node( int val = 0, Node* left = nullptr,
Node* right = nullptr)
: val(val)
, left(left)
, right(right)
{
}
};
bool is_prime( int num)
{
if (num < 2) {
return false ;
}
for ( int i = 2; i <= std:: sqrt (num); i++) {
if (num % i == 0) {
return false ;
}
}
return true ;
}
void print_primes_at_level(Node* root, int k)
{
std::queue<Node*> q;
q.push(root);
int curr_level = 1;
int curr_nodes = 1;
int next_nodes = 0;
std::vector< int > primes;
while (!q.empty()) {
Node* node = q.front();
q.pop();
if (is_prime(node->val) && curr_level == k) {
primes.push_back(node->val);
}
if (node->left) {
q.push(node->left);
next_nodes++;
}
if (node->right) {
q.push(node->right);
next_nodes++;
}
curr_nodes--;
if (curr_nodes == 0) {
if (!primes.empty()) {
std::cout << "Primes at level " << k
<< ": " ;
for ( int prime : primes) {
std::cout << prime << " " ;
}
std::cout << std::endl;
}
primes.clear();
curr_level++;
curr_nodes = next_nodes;
next_nodes = 0;
}
if (curr_level > k) {
break ;
}
}
}
int main()
{
Node* root = new Node(
2, new Node(3, new Node(7), new Node(11)),
new Node(5, new Node(13), new Node(17)));
print_primes_at_level(root, 1);
print_primes_at_level(root, 2);
print_primes_at_level(root, 3);
delete root->right->right;
delete root->right->left;
delete root->left->right;
delete root->left->left;
delete root->right;
delete root->left;
delete root;
return 0;
}
|
Java
import java.util.*;
class Node {
int val;
Node left;
Node right;
Node( int val) {
this .val = val;
left = null ;
right = null ;
}
}
public class GFG {
static boolean isPrime( int num) {
if (num < 2 ) {
return false ;
}
for ( int i = 2 ; i <= Math.sqrt(num); i++) {
if (num % i == 0 ) {
return false ;
}
}
return true ;
}
static void printPrimesAtLevel(Node root, int k) {
Queue<Node> q = new LinkedList<>();
q.add(root);
int currLevel = 1 ;
int currNodes = 1 ;
int nextNodes = 0 ;
List<Integer> primes = new ArrayList<>();
while (!q.isEmpty()) {
Node node = q.poll();
if (isPrime(node.val) && currLevel == k) {
primes.add(node.val);
}
if (node.left != null ) {
q.add(node.left);
nextNodes++;
}
if (node.right != null ) {
q.add(node.right);
nextNodes++;
}
currNodes--;
if (currNodes == 0 ) {
if (!primes.isEmpty()) {
System.out.print( "Primes at level " + k + ": " );
for ( int prime : primes) {
System.out.print(prime + " " );
}
System.out.println();
}
primes.clear();
currLevel++;
currNodes = nextNodes;
nextNodes = 0 ;
}
if (currLevel > k) {
break ;
}
}
}
public static void main(String[] args) {
Node root = new Node( 2 );
root.left = new Node( 3 );
root.right = new Node( 5 );
root.left.left = new Node( 7 );
root.left.right = new Node( 11 );
root.right.left = new Node( 13 );
root.right.right = new Node( 17 );
printPrimesAtLevel(root, 1 );
printPrimesAtLevel(root, 2 );
printPrimesAtLevel(root, 3 );
}
}
|
Python
import math
from Queue import Queue
class Node:
def __init__( self , val = None , left = None , right = None ):
self .val = val
self .left = left
self .right = right
def print_primes_at_level(root, k):
q = Queue()
q.put(root)
curr_level = 1
curr_nodes = 1
next_nodes = 0
primes = []
while not q.empty():
node = q.get()
if is_prime(node.val) and curr_level = = k:
primes.append(node.val)
if node.left:
q.put(node.left)
next_nodes + = 1
if node.right:
q.put(node.right)
next_nodes + = 1
curr_nodes - = 1
if curr_nodes = = 0 :
if primes:
print ( "primes at level {}: {}" . format (k, ' ' .join( str (p) for p in primes)))
primes = []
curr_level + = 1
curr_nodes = next_nodes
next_nodes = 0
if curr_level > k:
break
def is_prime(num):
if num < 2 :
return False
for i in range ( 2 , int (math.sqrt(num)) + 1 ):
if num % i = = 0 :
return False
return True
root = Node( 2 , Node( 3 , Node( 7 ), Node( 11 )), Node( 5 , Node( 13 ), Node( 17 )))
print_primes_at_level(root, 1 )
print_primes_at_level(root, 2 )
print_primes_at_level(root, 3 )
|
C#
using System;
using System.Collections.Generic;
class Node
{
public int val;
public Node left;
public Node right;
public Node( int val = 0, Node left = null , Node right = null )
{
this .val = val;
this .left = left;
this .right = right;
}
}
class GFG
{
static void PrintPrimesAtLevel(Node root, int k)
{
Queue<Node> queue = new Queue<Node>();
queue.Enqueue(root);
int currLevel = 1;
int currNodes = 1;
int nextNodes = 0;
List< int > primes = new List< int >();
while (queue.Count > 0)
{
Node node = queue.Dequeue();
if (IsPrime(node.val) && currLevel == k)
{
primes.Add(node.val);
}
if (node.left != null )
{
queue.Enqueue(node.left);
nextNodes++;
}
if (node.right != null )
{
queue.Enqueue(node.right);
nextNodes++;
}
currNodes--;
if (currNodes == 0)
{
if (primes.Count > 0)
{
Console.WriteLine($ "Primes at level {k}: {string.Join(" ", primes)}" );
}
primes.Clear();
currLevel++;
currNodes = nextNodes;
nextNodes = 0;
}
if (currLevel > k)
{
break ;
}
}
}
static bool IsPrime( int num)
{
if (num < 2)
{
return false ;
}
for ( int i = 2; i <= Math.Sqrt(num); i++)
{
if (num % i == 0)
{
return false ;
}
}
return true ;
}
static void Main()
{
Node root = new Node(2, new Node(3, new Node(7),
new Node(11)), new Node(5, new Node(13),
new Node(17)));
PrintPrimesAtLevel(root, 1);
PrintPrimesAtLevel(root, 2);
PrintPrimesAtLevel(root, 3);
}
}
|
Javascript
class Node {
constructor(val = 0, left = null , right = null ) {
this .val = val;
this .left = left;
this .right = right;
}
}
function isPrime(num) {
if (num < 2) {
return false ;
}
for (let i = 2; i <= Math.sqrt(num); i++) {
if (num % i === 0) {
return false ;
}
}
return true ;
}
function printPrimesAtLevel(root, k) {
const queue = [root];
let currLevel = 1;
let currNodes = 1;
let nextNodes = 0;
const primes = [];
while (queue.length > 0) {
const node = queue.shift();
if (isPrime(node.val) && currLevel === k) {
primes.push(node.val);
}
if (node.left) {
queue.push(node.left);
nextNodes++;
}
if (node.right) {
queue.push(node.right);
nextNodes++;
}
currNodes--;
if (currNodes === 0) {
if (primes.length > 0) {
console.log(`Primes at level ${k}: ${primes.join( ' ' )}`);
}
primes.length = 0;
currLevel++;
currNodes = nextNodes;
nextNodes = 0;
}
if (currLevel > k) {
break ;
}
}
}
const root = new Node(
2, new Node(3, new Node(7), new Node(11)),
new Node(5, new Node(13), new Node(17)));
printPrimesAtLevel(root, 1);
printPrimesAtLevel(root, 2);
printPrimesAtLevel(root, 3);
|
Output
primes at level 1: 2
primes at level 2: 3 5
primes at level 3: 7 11 13 17
Time Complexity: O(n), where n is the number of nodes in the binary tree.
Auxiliary Space: O(m), where m is the maximum number of nodes at a single level in the binary tree.
Last Updated :
13 Sep, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...