Given two Binary trees and two integer keys K1, K2 where both K1, K2 can be present in the same tree or in different trees. Let F1, F2 be the vectors representing the sequence of the vertices from root to K1 and K2 (K1 & K2 excluded), the task is to find the dot product of both of these vectors.
Note: There are no duplicates in the tree and both the trees are different from each other. In case if the keys are present at different depths, then only consider nodes till the same depth level.
Examples:
Input: K1 = 4, K2 = 5
Output: 5
Explanation:
Clearly from the 2 trees, both the keys are present in the first tree. The sequence of the vertices from the root to the K1 or F1 vector is, F1 = (1, 2) and F2 = (1, 2).
Now the dot product i.e. F1.F2 = 1×1 + 2×2 = 5.Input: K1 = 5, K2 = 7
Output: 6
Explanation:
F1 = (1, 2) and F2 = (6)
Since only need to consider the nodes till the same depth level, the dot product is F1.F2 = 1×6 = 6.
Approach: The idea is to find the tree in which the given key-value is present and then, calculate the dot product of the ancestors. Follow the steps below to solve the problem:
- Initialize two different auxiliary vectors.
- Store the ancestors of both the keys in the vectors.
- Traverse the vectors until the end of any one of the vectors is reached and keep on calculating the dot product of the corresponding elements of the vectors.
- Print the final dot product as the answer.
// C++ program for the above approach #include <bits/stdc++.h> using namespace std;
// Structure of the tree node struct node {
int data;
struct node* left;
struct node* right;
}; // Utility function to create a new node struct node* newNode( int data)
{ struct node* node
= ( struct node*) malloc (
sizeof ( struct node));
node->data = data;
node->left = NULL;
node->right = NULL;
return (node);
} // Function to store the ancestors // of the given key in the vector bool printAncestors( struct node* root,
int K, vector< int >& v)
{ // Base case
if (root == NULL)
return false ;
if (root->data == K)
return true ;
// If target is present in either left
// or right subtree of this node,
// then print this node
if (printAncestors(root->left, K, v)
|| printAncestors(root->right, K, v)) {
v.push_back(root->data);
return true ;
}
return false ;
} // Function to store the dot product of the vectors int dotProductOfVectors(vector< int >& v1, vector< int >& v2)
{ // Traverse the vectors from the end because the
// ancestors starts from the root of the
// tree and root of the tree is present at the end
int size1 = v1.size();
int size2 = v2.size();
int i = size1 - 1;
int j = size2 - 1;
int answer = 0;
// Traverse the vectors side by side and storing answer
while (i >= 0 && j >= 0) {
answer = answer + (v1[i] * v2[j]);
i--;
j--;
}
// Return dot product
return answer;
} // Utility function to calculate the dot product of // the ancestors of the keys int dotProductOfAncestorsUtil( struct node* root1,
struct node* root2, int K1,
int K2)
{ // To store the ancestors of each key
vector< int > F1, F2;
// If both keys are present in the first tree
if (printAncestors(root1, K1, F1)
&& printAncestors(root1, K2, F2)) {
return dotProductOfVectors(F1, F2);
}
// If both keys are present in the second tree
else if (printAncestors(root2, K1, F1)
&& printAncestors(root2, K2, F2)) {
return dotProductOfVectors(F1, F2);
}
// If first key exists in first tree and
// the second key exists in second tree
else if (printAncestors(root1, K1, F1)
&& printAncestors(root2, K2, F2)) {
return dotProductOfVectors(F1, F2);
}
// Otherwise, first key exists in second tree and
// the second key exists in first tree
else {
if (printAncestors(root2, K1, F1)
&& printAncestors(root1, K2, F2)) {
return dotProductOfVectors(F1, F2);
}
}
// If either of the nodes doesn't exist
return 0;
} void dotProductOfAncestors( struct node* root1,
struct node* root2, int K1,
int K2)
{ // To store dot product of two vectors
int dotProduct
= dotProductOfAncestorsUtil(root1, root2, K1, K2);
// Print dot product as the answer
cout << dotProduct;
} // Driver Code int main()
{ /* Construct the following binary trees
1 6
/ \ / \
2 3 7 8
/ \ / \
4 5 9 10
*/
// Given Tree 1
struct node* root1 = newNode(1);
root1->left = newNode(2);
root1->right = newNode(3);
root1->left->left = newNode(4);
root1->left->right = newNode(5);
// Given Tree 2
struct node* root2 = newNode(6);
root2->left = newNode(7);
root2->right = newNode(8);
root2->left->left = newNode(9);
root2->right->right = newNode(10);
// Given keys
int K1 = 4, K2 = 5;
// Function Call
dotProductOfAncestors(root1, root2, K1, K2);
} |
// Java program for the above approach import java.io.*;
import java.util.*;
class GFG
{ // Structure of the tree node
static class node
{
int data;
node left, right;
}
// Utility function to create a new node
static node newNode( int data)
{
node node = new node();
node.data = data;
node.left = null ;
node.right = null ;
return (node);
}
// Function to store the ancestors
// of the given key in the vector
static boolean printAncestors(node root, int K,
Vector<Integer> v)
{
// Base case
if (root == null )
return false ;
if (root.data == K)
return true ;
// If target is present in either left
// or right subtree of this node,
// then print this node
if (printAncestors(root.left, K, v)
|| printAncestors(root.right, K, v))
{
v.add(root.data);
return true ;
}
return false ;
}
// Function to store the dot product of the vectors
static int dotProductOfVectors(Vector<Integer> v1,
Vector<Integer> v2)
{
// Traverse the vectors from the end because the
// ancestors starts from the root of the
// tree and root of the tree is present at the end
int size1 = v1.size();
int size2 = v2.size();
int i = size1 - 1 ;
int j = size2 - 1 ;
int answer = 0 ;
// Traverse the vectors side by side and storing
// answer
while (i >= 0 && j >= 0 )
{
answer = answer + (v1.get(i) * v2.get(j));
i--;
j--;
}
// Return dot product
return answer;
}
// Utility function to calculate the dot product of
// the ancestors of the keys
static int dotProductOfAncestorsUtil(node root1,
node root2, int K1,
int K2)
{
// To store the ancestors of each key
Vector<Integer> F1 = new Vector<Integer>();
Vector<Integer> F2 = new Vector<Integer>();
// If both keys are present in the first tree
if (printAncestors(root1, K1, F1)
&& printAncestors(root1, K2, F2)) {
return dotProductOfVectors(F1, F2);
}
// If both keys are present in the second tree
else if (printAncestors(root2, K1, F1)
&& printAncestors(root2, K2, F2)) {
return dotProductOfVectors(F1, F2);
}
// If first key exists in first tree and
// the second key exists in second tree
else if (printAncestors(root1, K1, F1)
&& printAncestors(root2, K2, F2)) {
return dotProductOfVectors(F1, F2);
}
// Otherwise, first key exists in second tree and
// the second key exists in first tree
else {
if (printAncestors(root2, K1, F1)
&& printAncestors(root1, K2, F2)) {
return dotProductOfVectors(F1, F2);
}
}
// If either of the nodes doesn't exist
return 0 ;
}
static void dotProductOfAncestors(node root1,
node root2, int K1,
int K2)
{
// To store dot product of two vectors
int dotProduct = dotProductOfAncestorsUtil(
root1, root2, K1, K2);
// Print dot product as the answer
System.out.println(dotProduct);
}
// Driver Code
public static void main(String[] args)
{
/* Construct the following binary trees
1 6
/ \ / \
2 3 7 8
/ \ / \
4 5 9 10
*/
// Given Tree 1
node root1 = newNode( 1 );
root1.left = newNode( 2 );
root1.right = newNode( 3 );
root1.left.left = newNode( 4 );
root1.left.right = newNode( 5 );
// Given Tree 2
node root2 = newNode( 6 );
root2.left = newNode( 7 );
root2.right = newNode( 8 );
root2.left.left = newNode( 9 );
root2.right.right = newNode( 10 );
// Given keys
int K1 = 4 , K2 = 5 ;
// Function Call
dotProductOfAncestors(root1, root2, K1, K2);
}
} // This code is contributed by Dharanendra L V |
# Python3 program for the above approach # Structure of the tree node class Node:
def __init__( self , x):
self .data = x
self .left = None
self .right = None
# Function to store the ancestors # of the given key in the vector def printAncestors(root, K, v):
# Global v
if (root = = None ):
return False
if (root.data = = K):
return True
# If target is present in either left
# or right subtree of this node,
# then print this node
if (printAncestors(root.left, K, v) or
printAncestors(root.right, K, v)):
v.append(root.data)
return True
return False
# Function to store the dot product # of the vectors def dotProductOfVectors(v1, v2):
# Global v1,v2
# Ancestors starts from the root of
# the tree and root of the tree is
# present at the end
size1 = len (v1)
size2 = len (v2)
i = size1 - 1
j = size2 - 1
answer = 0
# Traverse the vectors side by
# side and storing answer
while (i > = 0 and j > = 0 ):
answer = answer + (v1[i] * v2[j])
i - = 1
j - = 1
# Return dot product
return answer
# Utility function to calculate the dot product # of the ancestors of the keys def dotProductOfAncestorsUtil(root1, root2,
K1, K2):
# To store the ancestors of each key
F1, F2 = [], []
# If both keys are present in the first tree
if (printAncestors(root1, K1, F1) and
printAncestors(root1, K2, F2)):
return dotProductOfVectors(F1, F2)
# If both keys are present in the second tree
elif (printAncestors(root2, K1, F1) and
printAncestors(root2, K2, F2)):
return dotProductOfVectors(F1, F2)
# If first key exists in first tree and
# the second key exists in second tree
elif (printAncestors(root1, K1, F1) and
printAncestors(root2, K2, F2)):
return dotProductOfVectors(F1, F2)
# Otherwise, first key exists in second tree
# and the second key exists in first tree
else :
if (printAncestors(root2, K1, F1) and
printAncestors(root1, K2, F2)):
return dotProductOfVectors(F1, F2)
# If either of the nodes doesn't exist
return 0
def dotProductOfAncestors(root1, root2, K1, K2):
# To store dot product of two vectors
dotProduct = dotProductOfAncestorsUtil(
root1, root2, K1, K2)
# Print dot product as the answer
print (dotProduct)
# Driver Code if __name__ = = '__main__' :
v, v1, v2 = [], [], []
# Construct the following binary trees
# 1 6
# / \ / \
# 2 3 7 8
# / \ / \
# 4 5 9 10
# Given Tree 1
root1 = Node( 1 )
root1.left = Node( 2 )
root1.right = Node( 3 )
root1.left.left = Node( 4 )
root1.left.right = Node( 5 )
# Given Tree 2
root2 = Node( 6 )
root2.left = Node( 7 )
root2.right = Node( 8 )
root2.left.left = Node( 9 )
root2.right.right = Node( 10 )
# Given keys
K1, K2 = 4 , 5
# Function Call
dotProductOfAncestors(root1, root2, K1, K2)
# This code is contributed by mohit kumar 29 |
// C# program for the above approach using System;
using System.Collections.Generic;
class GFG {
// Structure of the tree node
public class node
{
public int data;
public node left, right;
}
// Utility function to create a new node
public static node newNode( int data)
{
node Node = new node();
Node.data = data;
Node.left = null ;
Node.right = null ;
return (Node);
}
// Function to store the ancestors
// of the given key in the vector
static bool printAncestors(node root, int K, List< int > v)
{
// Base case
if (root == null )
return false ;
if (root.data == K)
return true ;
// If target is present in either left
// or right subtree of this node,
// then print this node
if (printAncestors(root.left, K, v)
|| printAncestors(root.right, K, v))
{
v.Add(root.data);
return true ;
}
return false ;
}
// Function to store the dot product of the vectors
static int dotProductOfVectors(List< int > v1, List< int > v2)
{
// Traverse the vectors from the end because the
// ancestors starts from the root of the
// tree and root of the tree is present at the end
int size1 = v1.Count;
int size2 = v2.Count;
int i = size1 - 1;
int j = size2 - 1;
int answer = 0;
// Traverse the vectors side by side and storing
// answer
while (i >= 0 && j >= 0)
{
answer = answer + (v1[i] * v2[j]);
i--;
j--;
}
// Return dot product
return answer;
}
// Utility function to calculate the dot product of
// the ancestors of the keys
static int dotProductOfAncestorsUtil(node root1,
node root2, int K1,
int K2)
{
// To store the ancestors of each key
List< int > F1 = new List< int >();
List< int > F2 = new List< int >();
// If both keys are present in the first tree
if (printAncestors(root1, K1, F1)
&& printAncestors(root1, K2, F2)) {
return dotProductOfVectors(F1, F2);
}
// If both keys are present in the second tree
else if (printAncestors(root2, K1, F1)
&& printAncestors(root2, K2, F2)) {
return dotProductOfVectors(F1, F2);
}
// If first key exists in first tree and
// the second key exists in second tree
else if (printAncestors(root1, K1, F1)
&& printAncestors(root2, K2, F2)) {
return dotProductOfVectors(F1, F2);
}
// Otherwise, first key exists in second tree and
// the second key exists in first tree
else {
if (printAncestors(root2, K1, F1)
&& printAncestors(root1, K2, F2)) {
return dotProductOfVectors(F1, F2);
}
}
// If either of the nodes doesn't exist
return 0;
}
static void dotProductOfAncestors(node root1,
node root2, int K1,
int K2)
{
// To store dot product of two vectors
int dotProduct = dotProductOfAncestorsUtil(
root1, root2, K1, K2);
// Print dot product as the answer
Console.WriteLine(dotProduct);
}
static void Main() {
/* Construct the following binary trees
1 6
/ \ / \
2 3 7 8
/ \ / \
4 5 9 10
*/
// Given Tree 1
node root1 = newNode(1);
root1.left = newNode(2);
root1.right = newNode(3);
root1.left.left = newNode(4);
root1.left.right = newNode(5);
// Given Tree 2
node root2 = newNode(6);
root2.left = newNode(7);
root2.right = newNode(8);
root2.left.left = newNode(9);
root2.right.right = newNode(10);
// Given keys
int K1 = 4, K2 = 5;
// Function Call
dotProductOfAncestors(root1, root2, K1, K2);
}
} // This code is contributed by divyeshrabadiya07. |
<script> // JavaScript program for the above approach
// Structure of the tree node
class node
{
constructor(data) {
this .left = null ;
this .right = null ;
this .data = data;
}
}
// Utility function to create a new node
function newNode(data)
{
let Node = new node(data);
return (Node);
}
// Function to store the ancestors
// of the given key in the vector
function printAncestors(root, K, v)
{
// Base case
if (root == null )
return false ;
if (root.data == K)
return true ;
// If target is present in either left
// or right subtree of this node,
// then print this node
if (printAncestors(root.left, K, v)
|| printAncestors(root.right, K, v))
{
v.push(root.data);
return true ;
}
return false ;
}
// Function to store the dot product of the vectors
function dotProductOfVectors(v1, v2)
{
// Traverse the vectors from the end because the
// ancestors starts from the root of the
// tree and root of the tree is present at the end
let size1 = v1.length;
let size2 = v2.length;
let i = size1 - 1;
let j = size2 - 1;
let answer = 0;
// Traverse the vectors side by side and storing
// answer
while (i >= 0 && j >= 0)
{
answer = answer + (v1[i] * v2[j]);
i--;
j--;
}
// Return dot product
return answer;
}
// Utility function to calculate the dot product of
// the ancestors of the keys
function dotProductOfAncestorsUtil(root1, root2, K1, K2)
{
// To store the ancestors of each key
let F1 = [];
let F2 = [];
// If both keys are present in the first tree
if (printAncestors(root1, K1, F1)
&& printAncestors(root1, K2, F2)) {
return dotProductOfVectors(F1, F2);
}
// If both keys are present in the second tree
else if (printAncestors(root2, K1, F1)
&& printAncestors(root2, K2, F2)) {
return dotProductOfVectors(F1, F2);
}
// If first key exists in first tree and
// the second key exists in second tree
else if (printAncestors(root1, K1, F1)
&& printAncestors(root2, K2, F2)) {
return dotProductOfVectors(F1, F2);
}
// Otherwise, first key exists in second tree and
// the second key exists in first tree
else {
if (printAncestors(root2, K1, F1)
&& printAncestors(root1, K2, F2)) {
return dotProductOfVectors(F1, F2);
}
}
// If either of the nodes doesn't exist
return 0;
}
function dotProductOfAncestors(root1, root2, K1, K2)
{
// To store dot product of two vectors
let dotProduct = dotProductOfAncestorsUtil(
root1, root2, K1, K2);
// Print dot product as the answer
document.write(dotProduct + "</br>" );
}
/* Construct the following binary trees
1 6
/ \ / \
2 3 7 8
/ \ / \
4 5 9 10
*/
// Given Tree 1
let root1 = newNode(1);
root1.left = newNode(2);
root1.right = newNode(3);
root1.left.left = newNode(4);
root1.left.right = newNode(5);
// Given Tree 2
let root2 = newNode(6);
root2.left = newNode(7);
root2.right = newNode(8);
root2.left.left = newNode(9);
root2.right.right = newNode(10);
// Given keys
let K1 = 4, K2 = 5;
// Function Call
dotProductOfAncestors(root1, root2, K1, K2);
</script> |
5
Time Complexity: O(N) where N is the number of nodes in the tree.
Auxiliary Space: O(N)