Distance between two nodes of a Tree

Posted: 26 Oct, 2020
Difficulty: Moderate

PROBLEM STATEMENT

Try Problem

Given a binary tree and the value of two nodes, find the distance between the given two nodes of the Binary Tree.

Distance between two nodes is defined as the minimum number of edges in the path from one node to another.

Input Format:
The first line of input contains an integer ‘T’ representing the number of test cases. Then the test cases follow.

The first line of each test case contains elements in the level order form, and all the node values in the given tree are unique. The line consists of values of nodes separated by a single space. In case a node is null, we take -1 in its place.

The second line of each test case contains two single-spaced integers, Node 1 and Node 2, representing the values of the two nodes.

For example, the input for the tree depicted in the below image would be:

example

1
2 3
4 -1 5 6
-1 7 -1 -1 -1 -1
-1 -1
7 5

Explanation:

First 5 lines represent the tree, and the last line contains the value of the nodes between which we have to find the distance.

Level 1:
The root node of the tree is 1

Level 2:
Left child of 1 = 2
Right child of 1 = 3

Level 3:
Left child of 2 = 4
Right child of 2 = null (-1)
Left child of 3 = 5
Right child of 3 = 6

Level 4:
Left child of 4 = null (-1)
Right child of 4 = 7
Left child of 5 = null (-1)
Right child of 5 = null (-1)
Left child of 6 = null (-1)
Right child of 6 = null (-1)

Level 5:
Left child of 7 = null (-1)
Right child of 7 = null (-1)

The first not-null node(of the previous level) is treated as the parent of the first two nodes of the current level. The second not-null node (of the previous level) is treated as the parent node for the next two nodes of the current level and so on.
The input ends when all nodes at the last level are null(-1). The last line contains the value of the two nodes (7 and 5) between which we have to find the distance.
Note:
The above format was just to provide clarity on how the input is formed for a given tree.
The sequence will be put together in a single line separated by a single space. Hence, for the above-depicted tree, the input will be given as:

1 2 3 4 -1 5 6 -1 7 -1 -1 -1 -1 -1 -1
7 5
Output Format:
For each test case, a single integer denoting the distance between the two nodes is printed. In case, if any of the nodes is not found in the tree, return -1.

The output for each test case is in a separate line.
Note:
You do not need to print anything, it has already been taken care of. Just implement the give function.
Constraints:
1 <= T <= 10 ^ 2
1 <= N <= 3 * 10 ^ 3
0 <= DATA <= 10 ^ 6 and DATA != -1

Where ‘T’ is the number of test cases, ‘N’ is the total number of nodes in the binary tree, and ‘DATA’ is the value of the binary tree node.

Time Limit: 1 sec.
Approach 1

In any rooted tree, the distance between two nodes 'U' and 'V' can be found by finding the lowest common ancestor (LCA), ‘x’ of two nodes. The lowest common ancestor (LCA) between nodes 'U' and 'V' is defined as the lowest node in the tree that has both 'U' and 'V' as descendants, where we define each node to be a descendant of itself (so if 'U' has a direct connection from 'V', 'V' is the lowest common ancestor).

 

The distance between 'U' and 'V' can be computed as the distance from the 'root' to 'U', plus the distance from the ‘root’ to 'V', minus twice the distance from the 'root' to the lowest common ancestor(LCA) of 'U' and 'V':

 

Distance(U, V) = Distance(root, U) + Distance(root, V) - 2 * Distance(root, LCA)

 

Where 'U' and 'V' are the two given nodes,

'root' is the root of a given binary tree,

“LCA” is the lowest common ancestor of 'U' and 'V',

Distance(U, V) is the distance between 'U' and 'V'.

 

Here, we subtract the distance from the 'root' to the LCA two times because it is added twice: once in Distance(root, U) and second in Distance(root, V).

 

For example:

For the above tree, the lowest common ancestor of nodes 5 and 6 is node 3, whereas, another common ancestor is 1.

 

Distance(1,5) is 2 as there are two edges in between 1 and 5 i.e. 1 -> 3 and 3 -> 5.

Distance(1,6) is 2 as there are two edges in between 1 and 6 i.e. 1 -> 3 and 3 -> 6.

Distance(1,3) is 1 as there is a direct edge between 1 and 3. Now, 1->3 is the edge that is not required to calculate the distance between two given nodes, so we need to subtract this distance twice because it is added two times, one in Distance(1, 5) and another in Distance(1, 6).

 

So, to generalise, we subtract the distance from the 'root' to the LCA two times because it is added twice: once in Distance(root, U) and second in Distance(root, V).

 

We have the following functions :

  • findDistanceBetweenNodes(): This is the main function that returns the distance between the two given nodes. It returns -1 if either node1 or node2 is not present in the binary tree.
    • To get the LCA of two given nodes, we simply make a call to the function findLCA() where we pass the root and the values of two given nodes, node1 and node2.
    • Now, we check if LCA is null or not. If yes, it means either node1 or node2 is not present in the binary tree. So, return -1.
    • Call the function findLevel() to get the distance of both the nodes and LCA from the root.
    • Calculate the final answer by using the above-explained formula and return it.

 

  • findLCA(): LCA of two nodes is the first common ancestor node of given nodes. This function recursively searches for the nodes, and if any of the nodes are found, then the node is returned or else null is returned. Hence, for a node to be the common ancestor, its left and the right child must return a non-null node. Steps are as follows:
    • Base cases:
      • If the root is NULL, then return NULL.
      • If any node is equal to the root, return it as LCA in this case.
    • Recursively check if the nodes exist in the left and the right subtree.
    • The current node will be the LCA of the given two nodes if both the subtree recursions (left and right) return a non-null node.
    • Else the LCA would be present in the subtree (left or right) that returns a non-null value.

 

  • findLevel(): This is a recursive function which returns distance (level) of a given node if it is present in the tree, otherwise returns -1.
    • Base cases:
      • If the root is NULL, then return -1.
      • If the root is the node that we are looking for, return the current level (distance).
    • Recursive case: Call the same function for the left and the right subtree of the root.

In this function, we recursively find the level (distance) of the given node by recursively calling the left and the right subtree. After each recursion level, we will increment the level variable by 1. Once we find the node that we are looking for, the level variable value will be returned, and the further processing of child nodes will be stopped. It is similar to finding the depth of a given node from the root.


 

Try Problem