Given a binary search tree and a target value, the task is to find the next greater element of the target value in the binary search tree.
Examples:
Input:
5
/ \
3 7
/ \ / \
2 4 6 8Target: 4
Output: 5
Explanation: The next greater element of 4 is 5Input:
4
/ \
2 6
/ \ \
1 3 8Target: 6
Output: 8
Explanation: The next greater element of 6 is 8
Approach: To solve the problem follow the below idea:
Finding the next greater element in a binary search tree involves performing an in-order traversal of the tree to create a sorted list of its node values. Once we have the sorted list of node values, we can easily find the next greater element of a given node by iterating through the list starting from the target node's value until we find a value greater than the node's value.
Below are the steps for the above approach:
- Perform an in-order traversal of the binary search tree and store its node values in a vector.
- Find the target node's value in the vector.
- Iterate through the vector starting from the target node's value until we find a value greater than the target node's value.
- If we find a value greater than the target node's value, return it as the next greater element. If we reach the end of the vector without finding a greater value, return -1 to indicate that the next greater element does not exist.
Below is the code for the above approach:
// C++ code for the above approach:
#include <bits/stdc++.h>
using namespace std;
// Definition for a binary
// search tree node.
struct TreeNode {
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int x)
: val(x), left(NULL), right(NULL)
{
}
};
void inorderTraversal(TreeNode* root, vector<int>& values)
{
if (!root)
return;
inorderTraversal(root->left, values);
values.push_back(root->val);
inorderTraversal(root->right, values);
}
int getNextGreaterElement(TreeNode* root, int target)
{
// To store the values of the binary
// search tree
vector<int> values;
// Perform in-order traversal and
// store values in the vector
inorderTraversal(root, values);
auto it
// Find target value in the vector
= find(values.begin(), values.end(), target);
// If target value is not found, return
// -1
if (it == values.end())
return -1;
// Calculate the distance between the target
// value and the beginning of the vector
auto dist = distance(values.begin(), it);
// Iterate over the vector starting
// from the target value
for (int i = dist + 1; i < values.size(); i++) {
// If an element greater than the
// target value is found, return it
if (values[i] > target) {
return values[i];
}
}
// If next greater element is not found,
// return -1
return -1;
}
// Drivers code
int main()
{
/*
* 5
* / \
* 3 7
* / \ / \
* 2 4 6 8
*/
TreeNode* root = new TreeNode(5);
root->left = new TreeNode(3);
root->right = new TreeNode(7);
root->left->left = new TreeNode(2);
root->left->right = new TreeNode(4);
root->right->left = new TreeNode(6);
root->right->right = new TreeNode(8);
int target = 4;
int nextGreaterElement
= getNextGreaterElement(root, target);
// Function Call
cout << "The next greater element of " << target
<< " is " << nextGreaterElement << endl;
return 0;
}
// Java code for the above approach:
import java.util.*;
// Definition for a binary
// search tree node.
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x)
{
val = x;
left = null;
right = null;
}
}
public class Main {
static void inorderTraversal(TreeNode root,
List<Integer> values)
{
if (root == null)
return;
inorderTraversal(root.left, values);
values.add(root.val);
inorderTraversal(root.right, values);
}
static int getNextGreaterElement(TreeNode root,
int target)
{
// To store the values of the binary
// search tree
List<Integer> values = new ArrayList<>();
// Perform in-order traversal and
// store values in the list
inorderTraversal(root, values);
// Find target value in the list
int dist = values.indexOf(target);
// If target value is not found, return -1
if (dist == -1)
return -1;
// Iterate over the list starting
// from the target value
for (int i = dist + 1; i < values.size(); i++) {
// If an element greater than the
// target value is found, return it
if (values.get(i) > target) {
return values.get(i);
}
}
// If next greater element is not found,
// return -1
return -1;
}
// Drivers code
public static void main(String[] args)
{
/*
* 5
* / \
* 3 7
* / \ / \
* 2 4 6 8
*/
TreeNode root = new TreeNode(5);
root.left = new TreeNode(3);
root.right = new TreeNode(7);
root.left.left = new TreeNode(2);
root.left.right = new TreeNode(4);
root.right.left = new TreeNode(6);
root.right.right = new TreeNode(8);
int target = 4;
int nextGreaterElement
= getNextGreaterElement(root, target);
// Function Call
System.out.println("The next greater element of "
+ target + " is "
+ nextGreaterElement);
}
}
// This code is contributed by Prajwal Kandekar
# Definition for a binary search tree node
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
# Function to perform in-order traversal and store values in the vector
def inorderTraversal(root, values):
if not root:
return
inorderTraversal(root.left, values)
values.append(root.val)
inorderTraversal(root.right, values)
# Function to get the next greater element of a target in the binary search tree
def getNextGreaterElement(root, target):
# To store the values of the binary search tree
values = []
# Perform in-order traversal and store values in the vector
inorderTraversal(root, values)
# Find target value in the vector
try:
index = values.index(target)
except ValueError:
return -1
# Iterate over the vector starting from the target value
for i in range(index + 1, len(values)):
# If an element greater than the target value is found, return it
if values[i] > target:
return values[i]
# If next greater element is not found, return -1
return -1
# Driver code
if __name__ == '__main__':
# Construct the binary search tree
"""
5
/ \
3 7
/ \ / \
2 4 6 8
"""
root = TreeNode(5)
root.left = TreeNode(3)
root.right = TreeNode(7)
root.left.left = TreeNode(2)
root.left.right = TreeNode(4)
root.right.left = TreeNode(6)
root.right.right = TreeNode(8)
# Target element to find the next greater element of
target = 4
# Function call
nextGreaterElement = getNextGreaterElement(root, target)
# Print the result
if nextGreaterElement == -1:
print(f"The next greater element of {target} is not found.")
else:
print(f"The next greater element of {target} is {nextGreaterElement}.")
// C# code for the above approach:
using System;
using System.Collections.Generic;
// Definition for a binary search tree node.
class TreeNode {
public int val;
public TreeNode left;
public TreeNode right;
public TreeNode(int x)
{
val = x;
left = null;
right = null;
}
}
public class GFG {
static void inorderTraversal(TreeNode root,
List<int> values)
{
if (root == null)
return;
inorderTraversal(root.left, values);
values.Add(root.val);
inorderTraversal(root.right, values);
}
static int getNextGreaterElement(TreeNode root,
int target)
{
// To store the values of the binary search tree
List<int> values = new List<int>();
// Perform in-order traversal and store values in
// the list
inorderTraversal(root, values);
// Find target value in the list
int dist = values.IndexOf(target);
// If target value is not found, return -1
if (dist == -1)
return -1;
// Iterate over the list starting from the target
// value
for (int i = dist + 1; i < values.Count; i++) {
// If an element greater than the target value
// is found, return it
if (values[i] > target) {
return values[i];
}
}
// If next greater element is not found, return -1
return -1;
}
static public void Main()
{
/*
* 5
* / \
* 3 7
* / \ / \
* 2 4 6 8
*/
TreeNode root = new TreeNode(5);
root.left = new TreeNode(3);
root.right = new TreeNode(7);
root.left.left = new TreeNode(2);
root.left.right = new TreeNode(4);
root.right.left = new TreeNode(6);
root.right.right = new TreeNode(8);
int target = 4;
int nextGreaterElement
= getNextGreaterElement(root, target);
// Function Call
Console.WriteLine("The next greater element of "
+ target + " is "
+ nextGreaterElement);
}
}
// This code is contributed by lokesh.
// Definition for a binary
// search tree node.
class TreeNode {
constructor(val) {
this.val = val;
this.left = null;
this.right = null;
}
}
function inorderTraversal(root, values) {
if (!root) return;
inorderTraversal(root.left, values);
values.push(root.val);
inorderTraversal(root.right, values);
}
function getNextGreaterElement(root, target) {
// To store the values of the binary
// search tree
const values = [];
// Perform in-order traversal and
// store values in the array
inorderTraversal(root, values);
// Find target value in the array
const idx = values.indexOf(target);
// If target value is not found, return -1
if (idx === -1) return -1;
// Iterate over the array starting from the
// target value index
for (let i = idx + 1; i < values.length; i++) {
// If an element greater than the target
// value is found, return it
if (values[i] > target) {
return values[i];
}
}
// If next greater element is not found,
// return -1
return -1;
}
// Driver code
(function main() {
/*
* 5
* / \
* 3 7
* / \ / \
* 2 4 6 8
*/
const root = new TreeNode(5);
root.left = new TreeNode(3);
root.right = new TreeNode(7);
root.left.left = new TreeNode(2);
root.left.right = new TreeNode(4);
root.right.left = new TreeNode(6);
root.right.right = new TreeNode(8);
const target = 4;
const nextGreaterElement = getNextGreaterElement(root, target);
// Function Call
console.log(`The next greater element of ${target} is ${nextGreaterElement}`);
})();
Output
The next greater element of 4 is 5
Time Complexity: O(n) where n is the number of nodes in the binary search tree.
Auxiliary Space: O(n), to store the node values in a vector.
Approach 2: Recursive Approach
Implementation :
#include <climits>
#include <iostream>
using namespace std;
struct Node {
int val;
Node* left;
Node* right;
Node(int value)
: val(value)
, left(nullptr)
, right(nullptr)
{
}
};
int findNextGreater(Node* root, int target)
{
int successor = INT_MAX;
while (root) {
if (root->val > target) {
successor = min(successor, root->val);
root = root->left;
}
else {
root = root->right;
}
}
return successor;
}
int main()
{
Node* root = new Node(2);
root->left = new Node(4);
root->right = new Node(7);
root->left->left = new Node(2);
root->left->right = new Node(3);
root->right->left = new Node(6);
root->right->right = new Node(9);
int target = 6;
int nextGreater = findNextGreater(root, target);
cout << "Next greater element after " << target
<< " is: " << nextGreater << endl;
// Clean up the memory
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;
}
import java.io.*;
class Node {
int val;
Node left;
Node right;
Node(int value) {
val = value;
left = null;
right = null;
}
}
public class Main {
public static int findNextGreater(Node root, int target) {
int successor = Integer.MAX_VALUE;
while (root != null) {
if (root.val > target) {
successor = Math.min(successor, root.val);
root = root.left;
} else {
root = root.right;
}
}
return successor;
}
public static void main(String[] args) {
Node root = new Node(2);
root.left = new Node(4);
root.right = new Node(7);
root.left.left = new Node(2);
root.left.right = new Node(3);
root.right.left = new Node(6);
root.right.right = new Node(9);
int target = 6;
int nextGreater = findNextGreater(root, target);
System.out.println("Next greater element after " + target + " is: " + nextGreater);
root.right.right = null;
root.right.left = null;
root.left.right = null;
root.left.left = null;
root.right = null;
root.left = null;
root = null;
}
}
class Node:
def __init__(self, value):
self.val = value
self.left = None
self.right = None
def findNextGreater(root, target):
successor = float('inf')
while root:
if root.val > target:
successor = min(successor, root.val)
root = root.left
else:
root = root.right
return successor
if __name__ == "__main__":
root = Node(2)
root.left = Node(4)
root.right = Node(7)
root.left.left = Node(2)
root.left.right = Node(3)
root.right.left = Node(6)
root.right.right = Node(9)
target = 6
nextGreater = findNextGreater(root, target)
print("Next greater element after", target, "is:", nextGreater)
root.right.right = None
root.right.left = None
root.left.right = None
root.left.left = None
root.right = None
root.left = None
root = None
using System;
public class Node
{
public int val;
public Node left;
public Node right;
public Node(int value)
{
val = value;
left = null;
right = null;
}
}
public class GFG
{
public static int FindNextGreater(Node root, int target)
{
int successor = int.MaxValue;
while (root != null)
{
if (root.val > target)
{
successor = Math.Min(successor, root.val);
root = root.left;
}
else
{
root = root.right;
}
}
return successor;
}
public static void Main()
{
Node root = new Node(2);
root.left = new Node(4);
root.right = new Node(7);
root.left.left = new Node(2);
root.left.right = new Node(3);
root.right.left = new Node(6);
root.right.right = new Node(9);
int target = 6;
int nextGreater = FindNextGreater(root, target);
Console.WriteLine("Next greater element after " + target + " is: " + nextGreater);
// Clean up the memory.
root.right.right = null;
root.right.left = null;
root.left.right = null;
root.left.left = null;
root.right = null;
root.left = null;
root = null;
}
}
class Node {
constructor(value) {
this.val = value;
this.left = null;
this.right = null;
}
}
function findNextGreater(root, target) {
let successor = Number.MAX_SAFE_INTEGER;
while (root) {
if (root.val > target) {
successor = Math.min(successor, root.val);
root = root.left;
} else {
root = root.right;
}
}
return successor;
}
// Driver code
let root = new Node(2);
root.left = new Node(4);
root.right = new Node(7);
root.left.left = new Node(2);
root.left.right = new Node(3);
root.right.left = new Node(6);
root.right.right = new Node(9);
let target = 6;
let nextGreater = findNextGreater(root, target);
// Clean up the memory
root.right.right = null;
root.right.left = null;
root.left.right = null;
root.left.left = null;
root.right = null;
root.left = null;
root = null;
console.log("Next greater element after " + target + " is: " + nextGreater);
Output
Next greater element after 6 is: 7