Find next smaller element in Binary Search Tree
Given a binary search tree and a target value, the task is to find the next smaller element of the target value in the binary search tree.
Examples :
Input:
8
/ \
3 10
/ \ \
1 6 14
/ \ /
4 7 13
Target: 7
Output: 6
Explanation: The next smaller element of 7 is 6
Input:
6
/ \
4 8
/ \ / \
2 5 7 10
Target: 5
Output: 4
Explanation: The next smaller element of 5 is 4
Approach1:
This approach to solve the problem is to do inorder traversal of the BST given and store each node while traversing in an array. Now, since inorder traversal of BST gives sorted elements, so we can do binary search to find next smaller element of target value in the array itself.
Below are the steps for the above approach:
- Define a structure for the node of the BST containing data, and pointers to the left and right child nodes.
- Create a function called ‘inorder‘ that takes the root node and a reference to an integer vector as parameters.
- Inside the ‘inorder‘ function, if the root node is NULL, return. Else, perform an inorder traversal of the BST by calling ‘inorder‘ recursively for the left child, pushing the data of the root node to the vector, and calling ‘inorder‘ recursively for the right child.
- Create a function called ‘nextSmallerElement‘ that takes the root node and the target value as parameters.
- Inside the ‘nextSmallerElement‘ function, call the ‘inorder‘ function passing the root node and a reference to a vector as parameters to store the inorder traversal of the BST.
- Get the size of the vector and initialize two variables left and right to 0 and n-1, respectively.
- Initialize an integer variable ‘index‘ to -1.
- While the left index is less than or equal to the right index, calculate the middle index using the formula (left + right) / 2.
- If the value at the middle index of the vector is less than the target value, set the ‘index‘ variable to the middle index, and move the ‘left‘ variable to mid+1.
- Else, set the ‘right‘ variable to mid-1.
- If no smaller element exists, return -1. Else, return the value at the ‘index‘ position in the vector.
- Create the root node of the BST, insert some nodes into the BST, and initialize the target value.
- Call the ‘nextSmallerElement‘ function passing the root node and the target value as parameters.
- Print the returned value from the ‘nextSmallerElement‘ function.
Below is the code for the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
struct Node {
int data;
Node *left, *right;
Node( int val)
{
data = val;
left = right = NULL;
}
};
void inorder(Node* root, vector< int >& nodes) {
if (root == NULL)
return ;
inorder(root->left, nodes);
nodes.push_back(root->data);
inorder(root->right, nodes);
}
int nextSmallerElement(Node* root, int target) {
vector< int > nodes;
inorder(root, nodes);
int n = nodes.size();
int left = 0, right = n - 1;
int index = -1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (nodes[mid] < target) {
index = mid;
left = mid + 1;
}
else
right = mid - 1;
}
if (index == -1)
return -1;
return nodes[index];
}
int main() {
Node* root = new Node(8);
root->left = new Node(3);
root->left->left = new Node(1);
root->left->right = new Node(6);
root->left->right->left = new Node(4);
root->left->right->right = new Node(7);
root->right = new Node(10);
root->right->right = new Node(14);
root->right->right->left = new Node(13);
int target = 7;
cout << nextSmallerElement(root, target);
return 0;
}
|
Java
import java.util.*;
class GFG {
static class Node {
int data;
Node left, right;
Node( int val)
{
data = val;
left = right = null ;
}
}
static void inorder(Node root, List<Integer> nodes) {
if (root == null )
return ;
inorder(root.left, nodes);
nodes.add(root.data);
inorder(root.right, nodes);
}
static int nextSmallerElement(Node root, int target) {
List<Integer> nodes = new ArrayList<>();
inorder(root, nodes);
int n = nodes.size();
int left = 0 , right = n - 1 ;
int index = - 1 ;
while (left <= right) {
int mid = left + (right - left) / 2 ;
if (nodes.get(mid) < target) {
index = mid;
left = mid + 1 ;
} else {
right = mid - 1 ;
}
}
if (index == - 1 )
return - 1 ;
return nodes.get(index);
}
public static void main(String[] args) {
Node root = new Node( 8 );
root.left = new Node( 3 );
root.left.left = new Node( 1 );
root.left.right = new Node( 6 );
root.left.right.left = new Node( 4 );
root.left.right.right = new Node( 7 );
root.right = new Node( 10 );
root.right.right = new Node( 14 );
root.right.right.left = new Node( 13 );
int target = 7 ;
System.out.println(nextSmallerElement(root, target));
}
}
|
Python3
class Node:
def __init__( self , val):
self .data = val
self .left = None
self .right = None
def inorder(root, nodes):
if root is None :
return
inorder(root.left, nodes)
nodes.append(root.data)
inorder(root.right, nodes)
def next_smaller_element(root, target):
nodes = []
inorder(root, nodes)
n = len (nodes)
left = 0
right = n - 1
index = - 1
while left < = right:
mid = left + (right - left) / / 2
if nodes[mid] < target:
index = mid
left = mid + 1
else :
right = mid - 1
if index = = - 1 :
return - 1
return nodes[index]
root = Node( 8 )
root.left = Node( 3 )
root.left.left = Node( 1 )
root.left.right = Node( 6 )
root.left.right.left = Node( 4 )
root.left.right.right = Node( 7 )
root.right = Node( 10 )
root.right.right = Node( 14 )
root.right.right.left = Node( 13 )
target = 7
print (next_smaller_element(root, target))
|
C#
using System;
using System.Collections.Generic;
public class Node {
public int data;
public Node left, right;
public Node( int val)
{
data = val;
left = right = null ;
}
}
public class GFG {
public static void Inorder(Node root, List< int > nodes)
{
if (root == null )
return ;
Inorder(root.left, nodes);
nodes.Add(root.data);
Inorder(root.right, nodes);
}
public static int NextSmallerElement(Node root,
int target)
{
List< int > nodes = new List< int >();
Inorder(root, nodes);
int n = nodes.Count;
int left = 0, right = n - 1;
int index = -1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (nodes[mid] < target) {
index = mid;
left = mid + 1;
}
else
right = mid - 1;
}
if (index == -1)
return -1;
return nodes[index];
}
public static void Main()
{
Node root = new Node(8);
root.left = new Node(3);
root.left.left = new Node(1);
root.left.right = new Node(6);
root.left.right.left = new Node(4);
root.left.right.right = new Node(7);
root.right = new Node(10);
root.right.right = new Node(14);
root.right.right.left = new Node(13);
int target = 7;
Console.WriteLine(NextSmallerElement(root, target));
}
}
|
Javascript
class Node {
constructor(val) {
this .data = val;
this .left = null ;
this .right = null ;
}
}
function inorder(root, nodes) {
if (root === null ) return ;
inorder(root.left, nodes);
nodes.push(root.data);
inorder(root.right, nodes);
}
function nextSmallerElement(root, target) {
const nodes = [];
inorder(root, nodes);
const n = nodes.length;
let left = 0;
let right = n - 1;
let index = -1;
while (left <= right) {
const mid = Math.floor((left + right) / 2);
if (nodes[mid] < target) {
index = mid;
left = mid + 1;
} else {
right = mid - 1;
}
}
if (index === -1) return -1;
return nodes[index];
}
const root = new Node(8);
root.left = new Node(3);
root.left.left = new Node(1);
root.left.right = new Node(6);
root.left.right.left = new Node(4);
root.left.right.right = new Node(7);
root.right = new Node(10);
root.right.right = new Node(14);
root.right.right.left = new Node(13);
const target = 7;
document.write(nextSmallerElement(root, target));
|
Time Complexity: O(N) where N is number of nodes in the BST given. This is because we are traversing each node of the tree.
Space Complexity: O(N) as we are storing nodes values in vector nodes. Here, N is number of nodes in the BST given.
Approach: To solve the problem follow the below idea:
Traverse the binary search tree to find the target node. If the target node has a left child, then the next smaller element will be the rightmost node in the left subtree. If the target node does not have a left child, then the next smaller element will be the first ancestor node that is greater than the target node.
Below are the steps for the above approach:
- Initialize a variable to store the next smaller element.
- Traverse the binary search tree to find the target node.
- If the target node has a left child, then traverse the right subtree of the left child until the rightmost node is found.
- If the target node does not have a left child, then traverse the ancestors of the target node until an ancestor node is found that is greater than the target node. Update the next smaller element if the ancestor node is smaller than the current next smaller element.
- Return the next smaller element.
Below is the code for the above approach:
C++
#include <iostream>
using namespace std;
struct Node {
int value;
Node* left;
Node* right;
Node( int val)
{
value = val;
left = NULL;
right = NULL;
}
};
int findNextSmaller(Node* root, int target)
{
int nextSmaller = -1;
Node* curr = root;
while (curr != NULL) {
if (curr->value == target) {
if (curr->left != NULL) {
curr = curr->left;
while (curr->right != NULL) {
curr = curr->right;
}
nextSmaller = curr->value;
}
break ;
}
else if (curr->value > target) {
curr = curr->left;
}
else {
if (curr->value > nextSmaller) {
nextSmaller = curr->value;
}
curr = curr->right;
}
}
return nextSmaller;
}
int main()
{
Node* root = new Node(8);
root->left = new Node(3);
root->left->left = new Node(1);
root->left->right = new Node(6);
root->left->right->left = new Node(4);
root->left->right->right = new Node(7);
root->right = new Node(10);
root->right->right = new Node(14);
root->right->right->left = new Node(13);
int target1 = 7;
int result1 = findNextSmaller(root, target1);
cout << result1 << endl;
return 0;
}
|
Java
import java.io.*;
class Node {
int value;
Node left;
Node right;
Node( int val)
{
value = val;
left = null ;
right = null ;
}
}
class GFG {
static int findNextSmaller(Node root, int target)
{
int nextSmaller = - 1 ;
Node curr = root;
while (curr != null ) {
if (curr.value == target) {
if (curr.left != null ) {
curr = curr.left;
while (curr.right != null ) {
curr = curr.right;
}
nextSmaller = curr.value;
}
break ;
}
else if (curr.value > target) {
curr = curr.left;
}
else {
if (curr.value > nextSmaller) {
nextSmaller = curr.value;
}
curr = curr.right;
}
}
return nextSmaller;
}
public static void main(String args[])
{
Node root = new Node( 8 );
root.left = new Node( 3 );
root.left.left = new Node( 1 );
root.left.right = new Node( 6 );
root.left.right.left = new Node( 4 );
root.left.right.right = new Node( 7 );
root.right = new Node( 10 );
root.right.right = new Node( 14 );
root.right.right.left = new Node( 13 );
int target1 = 7 ;
int result1 = findNextSmaller(root, target1);
System.out.println(result1);
}
}
|
Python3
class Node:
def __init__( self , val):
self .value = val
self .left = None
self .right = None
def findNextSmaller(root, target):
nextSmaller = - 1
curr = root
while curr is not None :
if curr.value = = target:
if curr.left is not None :
curr = curr.left
while curr.right is not None :
curr = curr.right
nextSmaller = curr.value
break
elif curr.value > target:
curr = curr.left
else :
if curr.value > nextSmaller:
nextSmaller = curr.value
curr = curr.right
return nextSmaller
if __name__ = = '__main__' :
root = Node( 8 )
root.left = Node( 3 )
root.left.left = Node( 1 )
root.left.right = Node( 6 )
root.left.right.left = Node( 4 )
root.left.right.right = Node( 7 )
root.right = Node( 10 )
root.right.right = Node( 14 )
root.right.right.left = Node( 13 )
target1 = 7
result1 = findNextSmaller(root, target1)
print (result1)
|
C#
using System;
public class Node {
public int value;
public Node left;
public Node right;
public Node( int val)
{
value = val;
left = null ;
right = null ;
}
}
public class GFG {
static int findNextSmaller(Node root, int target)
{
int nextSmaller = -1;
Node curr = root;
while (curr != null ) {
if (curr.value == target) {
if (curr.left != null ) {
curr = curr.left;
while (curr.right != null ) {
curr = curr.right;
}
nextSmaller = curr.value;
}
break ;
}
else if (curr.value > target) {
curr = curr.left;
}
else {
if (curr.value > nextSmaller) {
nextSmaller = curr.value;
}
curr = curr.right;
}
}
return nextSmaller;
}
static public void Main()
{
Node root = new Node(8);
root.left = new Node(3);
root.left.left = new Node(1);
root.left.right = new Node(6);
root.left.right.left = new Node(4);
root.left.right.right = new Node(7);
root.right = new Node(10);
root.right.right = new Node(14);
root.right.right.left = new Node(13);
int target1 = 7;
int result1 = findNextSmaller(root, target1);
Console.WriteLine(result1);
}
}
|
Javascript
class Node {
constructor(val) {
this .value = val;
this .left = null ;
this .right = null ;
}
}
function findNextSmaller(root, target) {
let nextSmaller = -1;
let curr = root;
while (curr !== null ) {
if (curr.value === target) {
if (curr.left !== null ) {
curr = curr.left;
while (curr.right !== null ) {
curr = curr.right;
}
nextSmaller = curr.value;
}
break ;
} else if (curr.value > target) {
curr = curr.left;
} else {
if (curr.value > nextSmaller) {
nextSmaller = curr.value;
}
curr = curr.right;
}
}
return nextSmaller;
}
function main() {
const root = new Node(8);
root.left = new Node(3);
root.left.left = new Node(1);
root.left.right = new Node(6);
root.left.right.left = new Node(4);
root.left.right.right = new Node(7);
root.right = new Node(10);
root.right.right = new Node(14);
root.right.right.left = new Node(13);
const target1 = 7;
const result1 = findNextSmaller(root, target1);
console.log(result1);
}
main();
|
Time Complexity: O(h)
Auxiliary Space: O(1)
Last Updated :
07 Nov, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...