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.
Feeling lost in the world of random DSA topics, wasting time without progress? It’s time for a change! Join our DSA course, where we’ll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!