Find two nodes in the BST whose product equals to the target value
Last Updated :
09 Jan, 2024
Given a binary search tree (BST) and a target value, find two nodes in the BST such that their product equals the given target value. Return an empty array if no such pair exists.
Examples:
Input:
5
/ \
3 8
/ \ / \
2 4 6 10
Output: 3 8
Explanation: 8 * 3 = 24
Input:
4
/ \
2 5
/ \ \
1 3 6
Output: 5 2
Explanation : 5*2 = 10
Approach1:
This approach to solve the problem is to do inorder traversal of the given BST and store it in an array. Now, use Two Pointer technique to get pairs whose products is equal to given target value. If no pair is found, return an empty vector.
Algorithm:
- Define a struct TreeNode for the nodes in a binary tree.
- Define a class Solution with the following methods:
- An inorder traversal function that takes a TreeNode pointer and a vector<int> reference as inputs. The function traverses the left subtree, stores the value of the current node in the vector, and traverses the right subtree.
- A findTarget function that takes a TreeNode pointer and an integer target as inputs and returns a vector<int>. The function first calls the inorder traversal function to obtain an inorder traversal of the binary search tree. It then initializes two indices l and r to the beginning and end of the inorder traversal vector, respectively. While l < r, the function calculates the product of the values at indices l and r, compares it with the target, and adjusts l and r accordingly. If the product equals the target, it adds the values at indices l and r to the result vector and breaks the loop. Finally, it returns the result vector.
- In the main function:
- Create a binary search tree according to the input specification.
- Initialize an integer target according to the input specification.
- Create an instance of the Solution class.
- Call the findTarget function with the root of the binary search tree and the target as inputs.
- Print the output according to the size of the returned vector.
Below is the implementation of the approach:
C++
#include <iostream>
#include <stack>
#include <vector>
using namespace std;
struct TreeNode {
int val;
TreeNode* left;
TreeNode* right;
TreeNode( int x)
: val(x)
, left(NULL)
, right(NULL)
{
}
};
class Solution {
public :
void inorder(TreeNode* root, vector< int > &in) {
if (root == NULL)
return ;
inorder(root->left, in);
in.push_back(root->val);
inorder(root->right, in);
}
vector< int > findTarget(TreeNode* root, int k) {
vector< int > in, res;
inorder(root, in);
int n = in.size();
int l = 0, r = n - 1;
while (l < r){
int prod = in[l] * in[r];
if ( prod == k ){
res.push_back(in[l]);
res.push_back(in[r]);
break ;
}
else if ( prod < k )
l++;
else
r--;
}
return res;
}
};
int main()
{
TreeNode* root = new TreeNode(5);
root->left = new TreeNode(3);
root->right = new TreeNode(8);
root->left->left = new TreeNode(2);
root->left->right = new TreeNode(4);
root->right->left = new TreeNode(6);
root->right->right = new TreeNode(10);
int target = 24;
Solution s;
vector< int > res = s.findTarget(root, target);
if (res.size() == 2)
cout << res[0] << " " << res[1] << endl;
else
cout << "No such pair exists in the BST." << endl;
return 0;
}
|
Java
import java.util.ArrayList;
import java.util.List;
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode( int x) { val = x; }
}
class Solution {
void inorder(TreeNode root, List<Integer> in)
{
if (root == null )
return ;
inorder(root.left, in);
in.add(root.val);
inorder(root.right, in);
}
List<Integer> findTarget(TreeNode root, int k)
{
List<Integer> in = new ArrayList<>();
List<Integer> res = new ArrayList<>();
inorder(root, in);
int n = in.size();
int l = 0 , r = n - 1 ;
while (l < r) {
int prod = in.get(l) * in.get(r);
if (prod == k) {
res.add(in.get(l));
res.add(in.get(r));
break ;
}
else if (prod < k)
l++;
else
r--;
}
return res;
}
}
public class GFG {
public static void main(String[] args)
{
TreeNode root = new TreeNode( 5 );
root.left = new TreeNode( 3 );
root.right = new TreeNode( 8 );
root.left.left = new TreeNode( 2 );
root.left.right = new TreeNode( 4 );
root.right.left = new TreeNode( 6 );
root.right.right = new TreeNode( 10 );
int target = 24 ;
Solution s = new Solution();
List<Integer> res = s.findTarget(root, target);
if (res.size() == 2 )
System.out.println(res.get( 0 ) + " "
+ res.get( 1 ));
else
System.out.println(
"No such pair exists in the BST." );
}
}
|
Python3
class TreeNode:
def __init__( self , x):
self .val = x
self .left = None
self .right = None
class Solution:
def inorder( self , root, in_order):
if root is None :
return
self .inorder(root.left, in_order)
in_order.append(root.val)
self .inorder(root.right, in_order)
def findTarget( self , root, k):
in_order, res = [], []
self .inorder(root, in_order)
n = len (in_order)
l, r = 0 , n - 1
while l < r:
prod = in_order[l] * in_order[r]
if prod = = k:
res.extend([in_order[l], in_order[r]])
break
elif prod < k:
l + = 1
else :
r - = 1
return res
if __name__ = = "__main__" :
root = TreeNode( 5 )
root.left = TreeNode( 3 )
root.right = TreeNode( 8 )
root.left.left = TreeNode( 2 )
root.left.right = TreeNode( 4 )
root.right.left = TreeNode( 6 )
root.right.right = TreeNode( 10 )
target = 24
s = Solution()
result = s.findTarget(root, target)
if len (result) = = 2 :
print (result[ 0 ], result[ 1 ])
else :
print ( "No such pair exists in the BST." )
|
C#
using System;
using System.Collections.Generic;
public class TreeNode {
public int val;
public TreeNode left;
public TreeNode right;
public TreeNode( int x)
{
val = x;
left = null ;
right = null ;
}
}
public class Solution {
private void Inorder(TreeNode root, List< int > inOrder)
{
if (root == null )
return ;
Inorder(root.left, inOrder);
inOrder.Add(root.val);
Inorder(root.right, inOrder);
}
public List< int > FindTarget(TreeNode root, int k)
{
List< int > inOrder = new List< int >();
List< int > res = new List< int >();
Inorder(root, inOrder);
int n = inOrder.Count;
int l = 0, r = n - 1;
while (l < r) {
int prod = inOrder[l] * inOrder[r];
if (prod == k) {
res.Add(inOrder[l]);
res.Add(inOrder[r]);
break ;
}
else if (prod < k)
l++;
else
r--;
}
return res;
}
}
public class GFG {
public static void Main( string [] args)
{
TreeNode root = new TreeNode(5);
root.left = new TreeNode(3);
root.right = new TreeNode(8);
root.left.left = new TreeNode(2);
root.left.right = new TreeNode(4);
root.right.left = new TreeNode(6);
root.right.right = new TreeNode(10);
int target = 24;
Solution s = new Solution();
List< int > res = s.FindTarget(root, target);
if (res.Count == 2)
Console.WriteLine(res[0] + " " + res[1]);
else
Console.WriteLine(
"No such pair exists in the BST." );
}
}
|
Javascript
class TreeNode {
constructor(val) {
this .val = val;
this .left = this .right = null ;
}
}
class Solution {
innorder(root, inn) {
if (root === null ) return ;
this .innorder(root.left, inn);
inn.push(root.val);
this .innorder(root.right, inn);
}
finndTarget(root, k) {
const inn = [];
const res = [];
this .innorder(root, inn);
const n = inn.length;
let l = 0,
r = n - 1;
while (l < r) {
const prod = inn[l] * inn[r];
if (prod === k) {
res.push(inn[l]);
res.push(inn[r]);
break ;
}
else if (prod < k) l++;
else r--;
}
return res;
}
}
const root = new TreeNode(5);
root.left = new TreeNode(3);
root.right = new TreeNode(8);
root.left.left = new TreeNode(2);
root.left.right = new TreeNode(4);
root.right.left = new TreeNode(6);
root.right.right = new TreeNode(10);
const target = 24;
const s = new Solution();
const res = s.finndTarget(root, target);
if (res.length === 2) {
console.log(res[0], res[1]);
} else {
console.log( "No such pair exists inn the BST." );
}
|
Time Complexity: O(N) where N is number of nodes in the given BST. This is because we are traversing each node once.
Space Complexity: O(N) as we are creating array of size N where N is number of nodes in the given BST.
Approach: This can be solved with the following idea:
- Perform inorder traversal for the BST from left to right and store the nodes in a stack.
- Perform inorder traversal for the BST from right to left and store the nodes in a stack.
- While either stack is not empty, get the top nodes of the two stacks.
- If the product of the top nodes is equal to the target value, then return the pair.
- If the product of the top nodes is less than the target value, then pop the top node from the left stack and move to its right subtree.
- If the product of the top nodes is greater than the target value, then pop the top node from the right stack and move to its left subtree.
- If no pair is found, return an empty vector.
Steps for the above approach:
- Create two stacks s1 and s2 for inorder traversal of the BST from left to right and right to left, respectively.
- Initialize current nodes curr1 and curr2 for the two in-order traversals, starting from the root of the BST.
- Loop until either stack is empty or a pair is found :
- Traverse the left subtree of the first tree (BST) and push each node onto s1 until curr1 becomes NULL.
- Traverse the right subtree of the second tree (BST) and push each node onto s2 until curr2 becomes NULL.
- If either stack is empty, break out of the loop.
- Get the top nodes of s1 and s2.
- If the product of the top nodes is equal to the target value, return the pair.
- If the product of the top nodes is less than the target value, pop the top node from s1 and move to its right subtree by setting curr1 = top1->right.
- If the product of the top nodes is greater than the target value, pop the top node from s2 and move to its left subtree by setting curr2 = top2->left.
- If no pair is found, return an empty vector.
Below is the code for the above approach :
C++
#include <iostream>
#include <stack>
#include <vector>
using namespace std;
struct TreeNode {
int val;
TreeNode* left;
TreeNode* right;
TreeNode( int x)
: val(x)
, left(NULL)
, right(NULL)
{
}
};
class Solution {
public :
vector< int > findTarget(TreeNode* root, int k)
{
vector< int > res;
stack<TreeNode*> s1, s2;
TreeNode* curr1 = root;
TreeNode* curr2 = root;
while (curr1 != NULL || !s1.empty() || curr2 != NULL
|| !s2.empty()) {
while (curr1 != NULL) {
s1.push(curr1);
curr1 = curr1->left;
}
while (curr2 != NULL) {
s2.push(curr2);
curr2 = curr2->right;
}
if (s1.empty() || s2.empty())
break ;
TreeNode* top1 = s1.top();
TreeNode* top2 = s2.top();
if (top1->val * top2->val == k) {
res.push_back(top1->val);
res.push_back(top2->val);
break ;
}
else if (top1->val * top2->val < k) {
s1.pop();
curr1 = top1->right;
}
else {
s2.pop();
curr2 = top2->left;
}
}
return res;
}
};
int main()
{
TreeNode* root = new TreeNode(5);
root->left = new TreeNode(3);
root->right = new TreeNode(8);
root->left->left = new TreeNode(2);
root->left->right = new TreeNode(4);
root->right->left = new TreeNode(6);
root->right->right = new TreeNode(10);
int target = 24;
Solution s;
vector< int > res = s.findTarget(root, target);
if (res.size() == 2)
cout << res[0] << " " << res[1] << endl;
else
cout << "No such pair exists in the BST." << endl;
return 0;
}
|
Java
import java.util.*;
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode( int x)
{
val = x;
left = null ;
right = null ;
}
}
class Solution {
public List<Integer> findTarget(TreeNode root, int k)
{
List<Integer> res = new ArrayList<>();
Stack<TreeNode> s1 = new Stack<>();
Stack<TreeNode> s2 = new Stack<>();
TreeNode curr1 = root;
TreeNode curr2 = root;
while (curr1 != null || !s1.empty() || curr2 != null
|| !s2.empty()) {
while (curr1 != null ) {
s1.push(curr1);
curr1 = curr1.left;
}
while (curr2 != null ) {
s2.push(curr2);
curr2 = curr2.right;
}
if (s1.empty() || s2.empty())
break ;
TreeNode top1 = s1.peek();
TreeNode top2 = s2.peek();
if (top1.val * top2.val == k) {
res.add(top1.val);
res.add(top2.val);
break ;
}
else if (top1.val * top2.val < k) {
s1.pop();
curr1 = top1.right;
}
else {
s2.pop();
curr2 = top2.left;
}
}
return res;
}
}
class GFG {
public static void main(String[] args)
{
TreeNode root = new TreeNode( 5 );
root.left = new TreeNode( 3 );
root.right = new TreeNode( 8 );
root.left.left = new TreeNode( 2 );
root.left.right = new TreeNode( 4 );
root.right.left = new TreeNode( 6 );
root.right.right = new TreeNode( 10 );
int target = 24 ;
Solution s = new Solution();
List<Integer> res = s.findTarget(root, target);
if (res.size() == 2 )
System.out.println(res.get( 0 ) + " "
+ res.get( 1 ));
else
System.out.println(
"No such pair exists in the BST." );
}
}
|
Python3
class TreeNode:
def __init__( self , val = 0 , left = None , right = None ):
self .val = val
self .left = left
self .right = right
class Solution:
def findTarget( self , root, k):
res = []
s1, s2 = [], []
curr1, curr2 = root, root
while curr1 or s1 or curr2 or s2:
while curr1:
s1.append(curr1)
curr1 = curr1.left
while curr2:
s2.append(curr2)
curr2 = curr2.right
if not s1 or not s2:
break
top1, top2 = s1[ - 1 ], s2[ - 1 ]
if top1.val * top2.val = = k:
res.extend([top1.val, top2.val])
break
elif top1.val * top2.val < k:
s1.pop()
curr1 = top1.right
else :
s2.pop()
curr2 = top2.left
return res
root = TreeNode( 5 )
root.left = TreeNode( 3 )
root.right = TreeNode( 8 )
root.left.left = TreeNode( 2 )
root.left.right = TreeNode( 4 )
root.right.left = TreeNode( 6 )
root.right.right = TreeNode( 10 )
target = 24
s = Solution()
res = s.findTarget(root, target)
if len (res) = = 2 :
print (res[ 0 ], res[ 1 ])
else :
print ( "No such pair exists in the BST." )
|
C#
using System;
using System.Collections.Generic;
public class TreeNode {
public int val;
public TreeNode left;
public TreeNode right;
public TreeNode( int x)
{
val = x;
left = null ;
right = null ;
}
}
public class Solution {
public List< int > FindTarget(TreeNode root, int k)
{
List< int > res = new List< int >();
Stack<TreeNode> s1 = new Stack<TreeNode>();
Stack<TreeNode> s2 = new Stack<TreeNode>();
TreeNode curr1 = root;
TreeNode curr2 = root;
while (curr1 != null || s1.Count > 0
|| curr2 != null || s2.Count > 0) {
while (curr1 != null ) {
s1.Push(curr1);
curr1 = curr1.left;
}
while (curr2 != null ) {
s2.Push(curr2);
curr2 = curr2.right;
}
if (s1.Count == 0 || s2.Count == 0)
break ;
TreeNode top1 = s1.Peek();
TreeNode top2 = s2.Peek();
if (top1.val * top2.val == k) {
res.Add(top1.val);
res.Add(top2.val);
break ;
}
else if (top1.val * top2.val < k) {
s1.Pop();
curr1 = top1.right;
}
else {
s2.Pop();
curr2 = top2.left;
}
}
return res;
}
}
public class GFG {
static public void Main()
{
TreeNode root = new TreeNode(5);
root.left = new TreeNode(3);
root.right = new TreeNode(8);
root.left.left = new TreeNode(2);
root.left.right = new TreeNode(4);
root.right.left = new TreeNode(6);
root.right.right = new TreeNode(10);
int target = 24;
Solution s = new Solution();
List< int > res = s.FindTarget(root, target);
if (res.Count == 2)
Console.WriteLine(res[0] + " " + res[1]);
else
Console.WriteLine(
"No such pair exists in the BST." );
}
}
|
Javascript
<script>
class TreeNode {
constructor(val) {
this .val = val;
this .left = null ;
this .right = null ;
}
}
class Solution {
findTarget(root, k) {
const res = [];
const s1 = [];
const s2 = [];
let curr1 = root;
let curr2 = root;
while (curr1 !== null || s1.length !== 0 || curr2 !== null || s2.length !== 0) {
while (curr1 !== null ) {
s1.push(curr1);
curr1 = curr1.left;
}
while (curr2 !== null ) {
s2.push(curr2);
curr2 = curr2.right;
}
if (s1.length === 0 || s2.length === 0)
break ;
const top1 = s1[s1.length - 1];
const top2 = s2[s2.length - 1];
if (top1.val * top2.val === k) {
res.push(top1.val);
res.push(top2.val);
break ;
}
else if (top1.val * top2.val < k) {
s1.pop();
curr1 = top1.right;
}
else {
s2.pop();
curr2 = top2.left;
}
}
return res;
}
}
const root = new TreeNode(5);
root.left = new TreeNode(3);
root.right = new TreeNode(8);
root.left.left = new TreeNode(2);
root.left.right = new TreeNode(4);
root.right.left = new TreeNode(6);
root.right.right = new TreeNode(10);
const target = 24;
const solution = new Solution();
const result = solution.findTarget(root, target);
if (result.length === 2)
document.write(result[0] + " " + result[1]);
else
document.write( "No such pair exists in the BST." );
</script>
|
Time Complexity: O(n), where n is the total number of nodes in the BST.
Auxiliary Space: O(h), where h is the height of the BST
Share your thoughts in the comments
Please Login to comment...