Shortest distance between two nodes in an infinite binary tree

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

filter_none

edit
close

play_arrow

link
brightness_4
code

// CPP 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 bewteen 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;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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 bewteen 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

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# 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 bewteen 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

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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 bewteen 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

chevron_right


Output:

Distance between 2 and 3 is : 2

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

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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 divison
        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;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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 divison
        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 

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# 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 divison 
        if x > y: 
            x = x >> 1
  
        # when the smaller becomes
        # the greater 
        if y > x: 
            y = y >> 1
            c += 1
      
    return
  
# Driver code 
if __name__ == "__main__":
  
    x, y = 4, 6
    print(Distance(x, y)) 
  
# This code is contributed by
# Rituraj Jain

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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 divison
        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

chevron_right


Output:

4

Time Complexity: O(log(max(x, y)))
Auxiliary Space: O(1)

The efficient approach has been suggested by Striver.



My Personal Notes arrow_drop_up

pawanasipugmailcom

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.