Shortest distance between two nodes in an infinite binary tree
Last Updated : 30 Aug, 2022
Consider you have an infinitely long binary tree having a pattern as below:
1 / \ 2 3 / \ / \ 4 5 6 7 / \ / \ / \ / \ . . . . . . . .
Given two nodes with values x and y. The task is to find the length of the shortest path between the two nodes.
Examples:
Input: x = 2, y = 3 Output: 2 Input: x = 4, y = 6 Output: 4
A naive approach is to store all the ancestors of both nodes in 2 Data-structures(vectors, arrays, etc..) and do a binary search for the first element(let index i) in vector1, and check if it exists in the vector2 or not. If it does, return the index(let x) of the element in vector2.
The answer will be thus
distance = v1.size() - 1 - i + v2.size() - 1 - x
Below is the implementation of the above approach.
C++ // C++ program to find distance // between two nodes // in a infinite binary tree #include <bits/stdc++.h> using namespace std; // to stores ancestors of first given node vector<int> v1; // to stores ancestors of first given node vector<int> v2; // normal binary search to find the element int BinarySearch(int x) { int low = 0; int high = v2.size() - 1; while (low <= high) { int mid = (low + high) / 2; if (v2[mid] == x) return mid; else if (v2[mid] > x) high = mid - 1; else low = mid + 1; } return -1; } // function to make ancestors of first node void MakeAncestorNode1(int x) { v1.clear(); while (x) { v1.push_back(x); x /= 2; } reverse(v1.begin(), v1.end()); } // function to make ancestors of second node void MakeAncestorNode2(int x) { v2.clear(); while (x) { v2.push_back(x); x /= 2; } reverse(v2.begin(), v2.end()); } // function to find distance between two nodes int Distance() { for (int i = v1.size() - 1; i >= 0; i--) { int x = BinarySearch(v1[i]); if (x != -1) { return v1.size() - 1 - i + v2.size() - 1 - x; } } } // Driver code int main() { int node1 = 2, node2 = 3; // find ancestors MakeAncestorNode1(node1); MakeAncestorNode2(node2); cout << "Distance between " << node1 << " and " << node2 << " is : " << Distance(); return 0; }
Java // Java program to find distance // between two nodes // in a infinite binary tree import java.util.*; class GFG { // to stores ancestors of first given node static Vector<Integer> v1 = new Vector<Integer>(); // to stores ancestors of first given node static Vector<Integer> v2 = new Vector<Integer>(); // normal binary search to find the element static int BinarySearch(int x) { int low = 0; int high = v2.size() - 1; while (low <= high) { int mid = (low + high) / 2; if (v2.get(mid) == x) return mid; else if (v2.get(mid) > x) high = mid - 1; else low = mid + 1; } return -1; } // function to make ancestors of first node static void MakeAncestorNode1(int x) { v1.clear(); while (x > 0) { v1.add(x); x /= 2; } Collections.reverse(v1); } // function to make ancestors of second node static void MakeAncestorNode2(int x) { v2.clear(); while (x > 0) { v2.add(x); x /= 2; } Collections.reverse(v2); } // function to find distance between two nodes static int Distance() { for (int i = v1.size() - 1; i >= 0; i--) { int x = BinarySearch(v1.get(i)); if (x != -1) { return v1.size() - 1 - i + v2.size() - 1 - x; } } return Integer.MAX_VALUE; } // Driver code public static void main(String[] args) { int node1 = 2, node2 = 3; // find ancestors MakeAncestorNode1(node1); MakeAncestorNode2(node2); System.out.print("Distance between " + node1 + " and " + node2 + " is : " + Distance()); } } // This code is contributed by 29AjayKumar
Python3 # Python3 program to find the distance between # two nodes in an infinite binary tree # normal binary search to find the element def BinarySearch(x): low = 0 high = len(v2) - 1 while low <= high: mid = (low + high) // 2 if v2[mid] == x: return mid elif v2[mid] > x: high = mid - 1 else: low = mid + 1 return -1 # Function to make ancestors of first node def MakeAncestorNode1(x): v1.clear() while x: v1.append(x) x //= 2 v1.reverse() # Function to make ancestors of second node def MakeAncestorNode2(x): v2.clear() while x: v2.append(x) x //= 2 v2.reverse() # Function to find distance between two nodes def Distance(): for i in range(len(v1) - 1, -1, -1): x = BinarySearch(v1[i]) if x != -1: return (len(v1) - 1 - i + len(v2) - 1 - x) # Driver code if __name__ == "__main__": node1, node2 = 2, 3 v1, v2 = [], [] # Find ancestors MakeAncestorNode1(node1) MakeAncestorNode2(node2) print("Distance between", node1, "and", node2, "is :", Distance()) # This code is contributed by Rituraj Jain
C# // C# program to find distance // between two nodes // in a infinite binary tree using System; using System.Collections.Generic; class GFG { // to stores ancestors of first given node static List<int> v1 = new List<int>(); // to stores ancestors of first given node static List<int> v2 = new List<int>(); // normal binary search to find the element static int BinarySearch(int x) { int low = 0; int high = v2.Count - 1; while (low <= high) { int mid = (low + high) / 2; if (v2[mid] == x) return mid; else if (v2[mid] > x) high = mid - 1; else low = mid + 1; } return -1; } // function to make ancestors of first node static void MakeAncestorNode1(int x) { v1.Clear(); while (x > 0) { v1.Add(x); x /= 2; } v1.Reverse(); } // function to make ancestors of second node static void MakeAncestorNode2(int x) { v2.Clear(); while (x > 0) { v2.Add(x); x /= 2; } v2.Reverse(); } // function to find distance between two nodes static int Distance() { for (int i = v1.Count - 1; i >= 0; i--) { int x = BinarySearch(v1[i]); if (x != -1) { return v1.Count - 1 - i + v2.Count - 1 - x; } } return int.MaxValue; } // Driver code public static void Main(String[] args) { int node1 = 2, node2 = 3; // find ancestors MakeAncestorNode1(node1); MakeAncestorNode2(node2); Console.Write("Distance between " + node1 + " and " + node2 + " is : " + Distance()); } } // This code is contributed by Princi Singh
JavaScript <script> // Javascript program to find distance // between two nodes // in a infinite binary tree // to stores ancestors of first given node let v1 = []; // to stores ancestors of first given node let v2 = []; // normal binary search to find the element function BinarySearch(x) { let low = 0; let high = v2.length - 1; while (low <= high) { let mid = Math.floor((low + high) / 2); if (v2[mid] == x) return mid; else if (v2[mid] > x) high = mid - 1; else low = mid + 1; } return -1; } // function to make ancestors of first node function MakeAncestorNode1(x) { v1=[]; while (x > 0) { v1.push(x); x = Math.floor(x/2); } v1.reverse(); } // function to make ancestors of second node function MakeAncestorNode2(x) { v2=[]; while (x > 0) { v2.push(x); x = Math.floor(x/2); } v2.reverse(); } // function to find distance between two nodes function Distance() { for (let i = v1.length - 1; i >= 0; i--) { let x = BinarySearch(v1[i]); if (x != -1) { return v1.length - 1 - i + v2.length - 1 - x; } } return Number.MAX_VALUE; } // Driver code let node1 = 2, node2 = 3; // find ancestors MakeAncestorNode1(node1); MakeAncestorNode2(node2); document.write("Distance between " + node1 + " and " + node2 + " is : " + Distance()); // This code is contributed by patel2127 </script>
OutputDistance between 2 and 3 is : 2
Complexity Analysis:
- Time Complexity: O(log(max(x, y)) * log(max(x, y)))
- Auxiliary Space: O(log(max(x, y)))
An efficient approach is to use the property of 2*x and 2*x+1 given. Keep dividing the larger of the two nodes by 2. If the larger becomes the smaller one, then divide the other one. At a stage, both the values will be the same, keep a count on the number of divisions done which will be the answer.
Below is the implementation of the above approach.
C++ // C++ program to find the distance // between two nodes in an infinite // binary tree #include <bits/stdc++.h> using namespace std; // function to find the distance // between two nodes in an infinite // binary tree int Distance(int x, int y) { // swap the smaller if (x < y) { swap(x, y); } int c = 0; // divide till x!=y while (x != y) { // keep a count ++c; // perform division if (x > y) x = x >> 1; // when the smaller // becomes the greater if (y > x) { y = y >> 1; ++c; } } return c; } // Driver code int main() { int x = 4, y = 6; cout << Distance(x, y); return 0; }
Java // Java program to find the distance // between two nodes in an infinite // binary tree class GFG { // function to find the distance // between two nodes in an infinite // binary tree static int Distance(int x, int y) { // swap the smaller if (x < y) { int temp = x; x = y; y = temp; } int c = 0; // divide till x!=y while (x != y) { // keep a count ++c; // perform division if (x > y) x = x >> 1; // when the smaller // becomes the greater if (y > x) { y = y >> 1; ++c; } } return c; } // Driver code public static void main(String[] args) { int x = 4, y = 6; System.out.println(Distance(x, y)); } } // This code is contributed by PrinciRaj1992
Python3 # Python3 program to find the distance between # two nodes in an infinite binary tree # Function to find the distance between # two nodes in an infinite binary tree def Distance(x, y): # Swap the smaller if x < y: x, y = y, x c = 0 # divide till x != y while x != y: # keep a count c += 1 # perform division if x > y: x = x >> 1 # when the smaller becomes # the greater if y > x: y = y >> 1 c += 1 return c # Driver code if __name__ == "__main__": x, y = 4, 6 print(Distance(x, y)) # This code is contributed by # Rituraj Jain
C# // C# program to find the distance // between two nodes in an infinite // binary tree using System; class GFG { // function to find the distance // between two nodes in an infinite // binary tree static int Distance(int x, int y) { // swap the smaller if (x < y) { int temp = x; x = y; y = temp; } int c = 0; // divide till x!=y while (x != y) { // keep a count ++c; // perform division if (x > y) x = x >> 1; // when the smaller // becomes the greater if (y > x) { y = y >> 1; ++c; } } return c; } // Driver code public static void Main(String[] args) { int x = 4, y = 6; Console.WriteLine(Distance(x, y)); } } // This code contributed by Rajput-Ji
JavaScript <script> // Javascript program to find the distance // between two nodes in an infinite // binary tree // Function to find the distance // between two nodes in an infinite // binary tree function Distance(x, y) { // Swap the smaller if (x < y) { let temp = x; x = y; y = temp; } let c = 0; // Divide till x!=y while (x != y) { // Keep a count ++c; // Perform division if (x > y) x = x >> 1; // When the smaller // becomes the greater if (y > x) { y = y >> 1; ++c; } } return c; } // Driver code let x = 4, y = 6; document.write(Distance(x, y)); // This code is contributed by suresh07 </script>
Complexity Analysis:
- Time Complexity: O(log(max(x, y)))
- Auxiliary Space: O(1)
The efficient approach has been suggested by Striver.
Another Approach:
The main idea is to use the formula Level(n) + Level(m) - 2* LCA(n,m) . So Level can easily be calculated using Log base 2 and LCA can be calculated by dividing the greater No. by 2 until n and m become equal.
Below is the implementation of the above approach:
C++ // C++ program to find the distance // between two nodes in an infinite // binary tree #include <bits/stdc++.h> using namespace std; int LCA(int n,int m) { // swap to keep n smallest if (n > m) { swap(n, m); } // a,b is level of n and m int a = log2(n); int b = log2(m); // divide until n!=m while (n != m) { if (n < m) m = m >> 1; if (n > m) n = n >> 1; } // now n==m which is the LCA of n ,m int v = log2(n); return a + b - 2 * v; } // Driver Code int main() { int n = 2, m = 6; // Function call cout << LCA(n,m) << endl; return 0; }
Java // Java program to find the distance // between two nodes in an infinite // binary tree import java.util.*; class GFG{ static int LCA(int n,int m) { // swap to keep n smallest if (n > m) { int temp = n; n = m; m = temp; } // a,b is level of n and m int a = (int)(Math.log(n) / Math.log(2)); int b = (int)(Math.log(m) / Math.log(2)); // divide until n!=m while (n != m) { if (n < m) m = m >> 1; if (n > m) n = n >> 1; } // now n==m which is the LCA of n ,m int v = (int)(Math.log(n) / Math.log(2)); return a + b - 2 * v; } // Driver Code public static void main(String[] args) { int n = 2, m = 6; // Function call System.out.print(LCA(n,m) +"\n"); } } // This code is contributed by umadevi9616
Python3 # python program to find the distance # between two nodes in an infinite # binary tree import math def LCA(n, m): # swap to keep n smallest if (n > m): n, m = m, n # a,b is level of n and m a = int(math.log2(n)) b = int(math.log2(m)) # divide until n!=m while (n != m): if (n < m): m = m >> 1 if (n > m): n = n >> 1 # now n==m which is the LCA of n ,m v = int(math.log2(n)) return a + b - 2 * v n = 2 m = 6 # Function call print(LCA(n,m)) # This code is contributed by shivanisinghss2110
C# // C# program to find the distance // between two nodes in an infinite // binary tree using System; class GFG{ static int LCA(int n,int m) { // swap to keep n smallest if (n > m) { int temp = n; n = m; m = temp; } // a,b is level of n and m int a = (int)(Math.Log(n) / Math.Log(2)); int b = (int)(Math.Log(m) / Math.Log(2)); // divide until n!=m while (n != m) { if (n < m) m = m >> 1; if (n > m) n = n >> 1; } // now n==m which is the LCA of n ,m int v = (int)(Math.Log(n) / Math.Log(2)); return a + b - 2 * v; } // Driver Code public static void Main(String[] args) { int n = 2, m = 6; // Function call Console.Write(LCA(n,m) +"\n"); } } // This code is contributed by shivanisinghss2110
JavaScript <script> // JavaScript program to find the distance // between two nodes in an infinite // binary tree function LCA(n, m) { // Swap to keep n smallest if (n > m) { let temp = n; n = m; m = temp; } // a,b is level of n and m let a = Math.log2(n); let b = Math.log2(m); // Divide until n!=m while (n != m) { if (n < m) m = m >> 1; if (n > m) n = n >> 1; } // Now n==m which is the LCA of n ,m let v = Math.log2(n); return a + b - 2 * v; } // Driver Code let n = 2, m = 6; // Function call document.write(LCA(n, m)); // This code is contributed by shivanisinghss2110 </script>
Complexity Analysis:
- Time Complexity: O(log(max(x, y)))
- Auxiliary Space: O(1)
Similar Reads
Find distance between two nodes of a Binary Tree
Given a Binary tree, the task is to find the distance between two keys in a binary tree, no parent pointers are given. The distance between two nodes is the minimum number of edges to be traversed to reach one node from another. The given two nodes are guaranteed to be in the binary tree and all nod
15+ min read
Queries to find distance between two nodes of a Binary tree
Given a binary tree, the task is to find the distance between two keys in a binary tree, no parent pointers are given. The distance between two nodes is the minimum number of edges to be traversed to reach one node from other. We have already discussed a method which uses segment tree to reduce the
15+ min read
Shortest Distance between Two Nodes in BST
Given the root of a Binary Search Tree and two keys, the task is to find the distance between the nodes with the given two keys. Note: The nodes with given keys always exist in the tree. Approach: Note: The given approach is optimal only for Binary Search Tree, we have discussed the same problem for
9 min read
Queries to find distance between two nodes of a Binary tree - O(logn) method
Given a binary tree, the task is to find the distance between two keys in a binary tree, no parent pointers are given. Distance between two nodes is the minimum number of edges to be traversed to reach one node from other. This problem has been already discussed in previous post but it uses three tr
15+ min read
Print all nodes between two given levels in Binary Tree
Given a binary tree, the task is to print all nodes between two given levels in a binary tree. Print the nodes level-wise, i.e., the nodes for any level should be printed from left to right. Note: The levels are 1-indexed, i.e., root node is at level 1. Example: Input: Binary tree, l = 2, h = 3 Outp
8 min read
Distance between two nodes of binary tree with node values from 1 to N
Given a binary tree with 1 as its root and for any parent i its left child will be 2*i and right child will be 2*i+1. The task is to find the minimum distance between two nodes n1 and n2. 1 / \ 2 3 / \ / \ 4 5 6 7 / \ / \ / \ / \ . . . . . . . . Examples: Input : n1 = 7, n2 = 10 Output : 5 Input : n
7 min read
Print path between any two nodes in a Binary Tree | Set 2
Given a Binary Tree of distinct nodes and a pair of nodes. The task is to find and print the path between the two given nodes in the binary tree.Examples: Input: N1 = 7, N2 = 4 Output: 7 3 1 4 Approach: An approach to solve this problem has been discussed in this article. In this article, an even op
15 min read
Print path between any two nodes in a Binary Tree
Given a Binary Tree of distinct nodes and a pair of nodes. The task is to find and print the path between the two given nodes in the binary tree. For Example, in the above binary tree the path between the nodes 7 and 4 is 7 -> 3 -> 1 -> 4. The idea is to find paths from root nodes to the tw
12 min read
Print nodes between two given level numbers of a binary tree
Given a binary tree and two level numbers 'low' and 'high', print nodes from level low to level high. For example consider the binary tree given in below diagram. Input: Root of below tree, low = 2, high = 4 Output: 8 22 4 12 10 14 A Simple Method is to first write a recursive function that prints n
10 min read
XOR of path between any two nodes in a Binary Tree
Given a binary tree with distinct nodes and a pair of two nodes. The task is to find the XOR of all of the nodes which comes on the path between the given two nodes. For Example, in the above binary tree for nodes (3, 5) XOR of path will be (3 XOR 1 XOR 0 XOR 2 XOR 5) = 5. The idea is to make use of
8 min read