Kth Smallest element in a Perfect Binary Search Tree
Given a Perfect BST with N nodes and an integer K, the task is to find the Kth smallest element is present in the tree.
Example:
Input:
K = 3, N = 15
50
/ \
30 70
/ \ / \
20 40 60 80
/\ /\ /\ / \
14 25 35 45 55 65 75 85
Output: 25
Explanation:
The 3rd smallest element
in the given BST is 25
Input:
K = 9, N = 15
50
/ \
30 70
/ \ / \
20 40 60 80
/\ /\ /\ / \
14 25 35 45 55 65 75 85
Output: 55
Explanation:
The 9th smallest element
in the given BST is 55
Naive Approach: Do the Inorder traversal in a perfect BST, such as morris traversal or recursive solution, which visits every node and returns the kth visit key. It takes O(N) time complexity to complete the task.
Efficient Approach:
Since the given BST is perfect and the number of nodes of the entire tree is already known, the computational complexity to solve the problem can be reduced to log(N). Follow the steps given below to solve the problem:
- in a perfect BST tree(N), |N| will always be odd in a perfect binary tree, the location of the median in any perfect BST is floor(|N|/2) + 1.
- Calculate the number of nodes in every sub-tree by dividing the total nodes as floor(|N| / 2).
- The left sub-tree of the Perfect BST will always contain the Kth smallest element if:
- K < location(median(N))=M this is because Mth smallest element will always be larger than the Kth smallest element and every element in the right sub-tree will be larger than the Mth smallest element
- The right sub-tree of Perfect BST will always contain a Rth smallest element if:
- K > location(median(N))=M, in this case, K – location(median(N))=R is the Rth smallest element in the right subtree. This is because Rth smallest element in the right sub-tree is larger than Mth smallest element and every element in the left-sub tree is smaller than Mth smallest element but Rth smallest element is larger than all of them. One may think of R as the new number when at least M smaller possibilities can be ignored. The Rth smallest element is the Kth smallest element when recurring into the right sub-tree (But keep in mind that R != K !).
- If K is location(median(T)), then that node contains the Kth smallest element in perfect BST.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
struct Node
{
int key;
Node *left, *right;
};
Node* newNode( int item)
{
Node* temp = new Node;
temp->key = item;
temp->left = temp->right = NULL;
return temp;
}
Node* insert(Node* node, int key)
{
if (node == NULL)
return newNode(key);
if (key < node->key)
node->left = insert(node->left, key);
else if (key > node->key)
node->right = insert(node->right, key);
return node;
}
bool KSmallestPerfectBST(Node* root, int k,
int treeSize,
int & kth_smallest)
{
if (root == NULL)
return false ;
int median_loc = (treeSize / 2) + 1;
if (k == median_loc)
{
kth_smallest = root->key;
return true ;
}
int newTreeSize = treeSize / 2;
if (k < median_loc)
{
return KSmallestPerfectBST(
root->left, k,
newTreeSize, kth_smallest);
}
int newK = k - median_loc;
return KSmallestPerfectBST(root->right, newK,
newTreeSize,
kth_smallest);
}
int main()
{
Node* root = NULL;
root = insert(root, 50);
insert(root, 30);
insert(root, 20);
insert(root, 40);
insert(root, 70);
insert(root, 60);
insert(root, 80);
insert(root, 14);
insert(root, 25);
insert(root, 35);
insert(root, 45);
insert(root, 55);
insert(root, 65);
insert(root, 75);
insert(root, 85);
int n = 15, k = 5;
int ans = -1;
if (KSmallestPerfectBST(root, k, n, ans)) {
cout << ans << " " ;
}
return 0;
}
|
Java
import java.util.*;
class GFG{
static class Node
{
int key;
Node left, right;
};
static int kth_smallest;
public static Node newNode( int item)
{
Node temp = new Node();
temp.key = item;
temp.left = temp.right = null ;
return temp;
}
static Node insert(Node node, int key)
{
if (node == null )
return newNode(key);
if (key < node.key)
node.left = insert(node.left, key);
else if (key > node.key)
node.right = insert(node.right, key);
return node;
}
static boolean KSmallestPerfectBST(Node root, int k,
int treeSize)
{
if (root == null )
return false ;
int median_loc = (treeSize / 2 ) + 1 ;
if (k == median_loc)
{
kth_smallest = root.key;
return true ;
}
int newTreeSize = treeSize / 2 ;
if (k < median_loc)
{
return KSmallestPerfectBST(
root.left, k,
newTreeSize);
}
int newK = k - median_loc;
return KSmallestPerfectBST(root.right, newK,
newTreeSize);
}
public static void main(String[] args)
{
Node root = null ;
root = insert(root, 50 );
insert(root, 30 );
insert(root, 20 );
insert(root, 40 );
insert(root, 70 );
insert(root, 60 );
insert(root, 80 );
insert(root, 14 );
insert(root, 25 );
insert(root, 35 );
insert(root, 45 );
insert(root, 55 );
insert(root, 65 );
insert(root, 75 );
insert(root, 85 );
int n = 15 , k = 5 ;
if (KSmallestPerfectBST(root, k, n))
{
System.out.print(kth_smallest + " " );
}
}
}
|
Python3
kth_smallest = 0
class newNode:
def __init__( self , item):
self .key = item
self .left = None
self .right = None
def insert(node, key):
if (node = = None ):
return newNode(key)
if (key < node.key):
node.left = insert(node.left, key)
elif (key > node.key):
node.right = insert(node.right, key)
return node
def KSmallestPerfectBST(root, k, treeSize):
global kth_smallest
if (root = = None ):
return False
median_loc = (treeSize / / 2 ) + 1
if (k = = median_loc):
kth_smallest = root.key
return True
newTreeSize = treeSize / / 2
if (k < median_loc):
return KSmallestPerfectBST(root.left,
k, newTreeSize)
newK = k - median_loc
return KSmallestPerfectBST(root.right, newK,
newTreeSize)
if __name__ = = '__main__' :
root = None
root = insert(root, 50 )
insert(root, 30 )
insert(root, 20 )
insert(root, 40 )
insert(root, 70 )
insert(root, 60 )
insert(root, 80 )
insert(root, 14 )
insert(root, 25 )
insert(root, 35 )
insert(root, 45 )
insert(root, 55 )
insert(root, 65 )
insert(root, 75 )
insert(root, 85 )
n = 15
k = 5
if (KSmallestPerfectBST(root, k, n)):
print (kth_smallest, end = " " )
|
C#
using System;
class GFG{
public class Node
{
public int key;
public Node left,
right;
};
static int kth_smallest;
public static Node newNode( int item)
{
Node temp = new Node();
temp.key = item;
temp.left = temp.right = null ;
return temp;
}
static Node insert(Node node,
int key)
{
if (node == null )
return newNode(key);
if (key < node.key)
node.left = insert(node.left,
key);
else if (key > node.key)
node.right = insert(node.right,
key);
return node;
}
static bool KSmallestPerfectBST(Node root, int k,
int treeSize)
{
if (root == null )
return false ;
int median_loc = (treeSize / 2) + 1;
if (k == median_loc)
{
kth_smallest = root.key;
return true ;
}
int newTreeSize = treeSize / 2;
if (k < median_loc)
{
return KSmallestPerfectBST(root.left, k,
newTreeSize);
}
int newK = k - median_loc;
return KSmallestPerfectBST(root.right, newK,
newTreeSize);
}
public static void Main(String[] args)
{
Node root = null ;
root = insert(root, 50);
insert(root, 30);
insert(root, 20);
insert(root, 40);
insert(root, 70);
insert(root, 60);
insert(root, 80);
insert(root, 14);
insert(root, 25);
insert(root, 35);
insert(root, 45);
insert(root, 55);
insert(root, 65);
insert(root, 75);
insert(root, 85);
int n = 15, k = 5;
if (KSmallestPerfectBST(root,
k, n))
{
Console.Write(kth_smallest + " " );
}
}
}
|
Javascript
<script>
class Node
{
constructor()
{
this .key = 0;
this .left = null ;
this .right = null ;
}
};
var kth_smallest;
function newNode(item)
{
var temp = new Node();
temp.key = item;
temp.left = temp.right = null ;
return temp;
}
function insert( node, key)
{
if (node == null )
return newNode(key);
if (key < node.key)
node.left = insert(node.left,
key);
else if (key > node.key)
node.right = insert(node.right,
key);
return node;
}
function KSmallestPerfectBST(root, k, treeSize)
{
if (root == null )
return false ;
var median_loc = parseInt(treeSize / 2) + 1;
if (k == median_loc)
{
kth_smallest = root.key;
return true ;
}
var newTreeSize = parseInt(treeSize / 2);
if (k < median_loc)
{
return KSmallestPerfectBST(root.left, k,
newTreeSize);
}
var newK = k - median_loc;
return KSmallestPerfectBST(root.right, newK,
newTreeSize);
}
var root = null ;
root = insert(root, 50);
insert(root, 30);
insert(root, 20);
insert(root, 40);
insert(root, 70);
insert(root, 60);
insert(root, 80);
insert(root, 14);
insert(root, 25);
insert(root, 35);
insert(root, 45);
insert(root, 55);
insert(root, 65);
insert(root, 75);
insert(root, 85);
var n = 15, k = 5;
if (KSmallestPerfectBST(root,
k, n))
{
document.write(kth_smallest + " " );
}
</script>
|
Time complexity: O(Log(N))
Auxiliary Space: O(Log(N))
Last Updated :
30 Jun, 2021
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...