Given a binary search tree, the task is to find the median of the subtree rooted with Kth smallest node of the tree.
Examples:
Input: N = 12, K = 9
50 / \ 25 75 / \ \ 15 45 90 / \ / \ / \ 11 20 30 49 80 100
Output: 85 Explanation: K=9. So the 9th smallest number is 75. The values of this subtree are 75 80 90 100. Now, the median of this is (80+90)/2 = 85
Approach: This can be solved with the following idea:
As it is BST, Inorder traversal of tree will give us sorted array. From there we can get the Kth smallest node. After that, iterate for that particular node and get the median.
Below are the steps involved:
- Intialize a nodes of vector v.
- Traverse in inorder, So as to get sorted vector.
- Get the Kth smallest node.
- Again Iterate in inorder traversal for kth samllest node and store them in another vector.
- Once done, check the size of vector:
- If even, median will be sum of both mid divide by 2.
- If odd, median will be mid of vector.
Below is the implementation of the code:
C++
#include <bits/stdc++.h>
using namespace std;
struct Node {
int data;
Node* left;
Node* right;
};
Node* newNode( int data)
{
Node* temp = new Node;
temp->data = data;
temp->left = temp->right = NULL;
return temp;
}
Node* insert(Node* root, int data)
{
if (root == NULL)
root = newNode(data);
else if (data < root->data)
root->left = insert(root->left, data);
else
root->right = insert(root->right, data);
return root;
}
void inorder(vector<Node*>& v, Node* root)
{
if (root == NULL) {
return ;
}
inorder(v, root->left);
v.push_back(root);
inorder(v, root->right);
return ;
}
int median(Node* node, int k)
{
vector<Node*> v;
inorder(v, node);
vector<Node*> v1;
inorder(v1, v[k - 1]);
if (v1.size() % 2 == 0) {
int mid = v1.size() / 2;
return (v1[mid]->data + v1[mid - 1]->data) / 2;
}
return v1[v1.size() / 2]->data;
return 0;
}
int main()
{
Node* root = NULL;
int n = 4;
int k = 2;
vector< int > nodes = { 3, 2, 4, 1 };
for ( int i = 0; i < n; i++) {
int x = nodes[i];
root = insert(root, x);
}
cout << median(root, k) << endl;
return 0;
}
|
Java
import java.util.ArrayList;
import java.util.List;
class Node {
int data;
Node left, right;
Node( int data) {
this .data = data;
left = right = null ;
}
}
public class Main {
static Node insert(Node root, int data) {
if (root == null )
return new Node(data);
else if (data < root.data)
root.left = insert(root.left, data);
else
root.right = insert(root.right, data);
return root;
}
static void inorder(List<Node> v, Node root) {
if (root == null ) {
return ;
}
inorder(v, root.left);
v.add(root);
inorder(v, root.right);
}
static int median(Node node, int k) {
List<Node> v = new ArrayList<>();
inorder(v, node);
List<Node> v1 = new ArrayList<>();
inorder(v1, v.get(k - 1 ));
if (v1.size() % 2 == 0 ) {
int mid = v1.size() / 2 ;
return (v1.get(mid).data + v1.get(mid - 1 ).data) / 2 ;
}
return v1.get(v1.size() / 2 ).data;
}
public static void main(String[] args) {
Node root = null ;
int n = 4 ;
int k = 2 ;
int [] nodes = { 3 , 2 , 4 , 1 };
for ( int i = 0 ; i < n; i++) {
int x = nodes[i];
root = insert(root, x);
}
System.out.println(median(root, k));
}
}
|
Python3
class Node:
def __init__( self , data):
self .data = data
self .left = None
self .right = None
def insert(root, data):
if root is None :
return Node(data)
elif data < root.data:
root.left = insert(root.left, data)
else :
root.right = insert(root.right, data)
return root
def inorder(v, root):
if root is None :
return
inorder(v, root.left)
v.append(root)
inorder(v, root.right)
def median(node, k):
v = []
inorder(v, node)
v1 = []
inorder(v1, v[k - 1 ])
if len (v1) % 2 = = 0 :
mid = len (v1) / / 2
return (v1[mid].data + v1[mid - 1 ].data) / / 2
return v1[ len (v1) / / 2 ].data
if __name__ = = "__main__" :
root = None
n = 4
k = 2
nodes = [ 3 , 2 , 4 , 1 ]
for x in nodes:
root = insert(root, x)
print (median(root, k))
|
C#
using System;
using System.Collections.Generic;
public class Node
{
public int data;
public Node left, right;
public Node( int data)
{
this .data = data;
left = right = null ;
}
}
public class Program
{
static Node Insert(Node root, int data)
{
if (root == null )
return new Node(data);
else if (data < root.data)
root.left = Insert(root.left, data);
else
root.right = Insert(root.right, data);
return root;
}
static void Inorder(List<Node> v, Node root)
{
if (root == null )
{
return ;
}
Inorder(v, root.left);
v.Add(root);
Inorder(v, root.right);
}
static int Median(Node node, int k)
{
List<Node> v = new List<Node>();
Inorder(v, node);
List<Node> v1 = new List<Node>();
Inorder(v1, v[k - 1]);
if (v1.Count % 2 == 0)
{
int mid = v1.Count / 2;
return (v1[mid].data + v1[mid - 1].data) / 2;
}
return v1[v1.Count / 2].data;
}
public static void Main()
{
Node root = null ;
int n = 4;
int k = 2;
int [] nodes = { 3, 2, 4, 1 };
for ( int i = 0; i < n; i++)
{
int x = nodes[i];
root = Insert(root, x);
}
Console.WriteLine(Median(root, k));
}
}
|
Javascript
class Node {
constructor(data) {
this .data = data;
this .left = null ;
this .right = null ;
}
}
function insert(root, data) {
if (root === null )
return new Node(data);
else if (data < root.data)
root.left = insert(root.left, data);
else
root.right = insert(root.right, data);
return root;
}
function inorder(v, root) {
if (root === null ) {
return ;
}
inorder(v, root.left);
v.push(root);
inorder(v, root.right);
}
function median(node, k) {
const v = [];
inorder(v, node);
const v1 = [];
inorder(v1, v[k - 1]);
if (v1.length % 2 === 0) {
const mid = v1.length / 2;
return Math.floor((v1[mid].data + v1[mid - 1].data) / 2);
}
return v1[Math.floor(v1.length / 2)].data;
}
let root = null ;
const n = 4;
const k = 2;
const nodes = [3, 2, 4, 1];
for (let i = 0; i < n; i++) {
const x = nodes[i];
root = insert(root, x);
}
console.log(median(root, k));
|
Time Complexity: O(N) Auxiliary Space: O(N)
|