Related Articles

# Program to calculate dot product of ancestors of 2 given nodes

• Difficulty Level : Hard
• Last Updated : 18 Jun, 2021

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++

 `// C++ program for the above approach` `#include ``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 vwctors``    ``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

 `// 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 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 v1,``                                 ``Vector 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 F1 = ``new` `Vector();``    ``Vector F2 = ``new` `Vector();` `    ``// 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 vwctors``    ``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

 `# 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 prthis 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 vwctors``    ``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#

 `// 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 vwctors``    ``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.`

## Javascript

 ``
Output:
`5`

Time Complexity: O(N) where N is the number of nodes in the tree.
Auxiliary Space: O(N)

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.

My Personal Notes arrow_drop_up