Open In App

Minimum distance between two given nodes in an N-ary tree

Last Updated : 16 Sep, 2021
Improve
Improve
Like Article
Like
Save
Share
Report

Given a N ary Tree consisting of N nodes, the task is to find the minimum distance from node A to node B of the tree.

Examples:

Input:              
         1          
    /         \      
  2            3    
 /  \       /  \   \
4   5    6    7   8
A = 4, B = 3
Output: 3
Explanation: The path 4->2->1->3 gives the minimum distance from A to B.

Input:
         1          
   /         \      
2            3    
          /  \  \
       6    7   8
A = 6, B = 7
Output: 2

 

Approach: This problem can be solved by using concept of LCA(Lowest Common Ancestor). Minimum distance between two given nodes A and B can be found out by using formula –
mindistance(A, B) = dist (LCA, A) + dist (LCA, B)
Follow the steps below to solve the problem:

  1. Find path from root node to the nodes A and B, respectively and simultaneously store the two paths in two arrays.
  2. Now iterate until values of both the arrays are same and value just before mismatch is the LCA node value.
  3. The value just before mismatch is the LCA node value.
  4. Find distance from the LCA node to node A and B, which can be found with the given steps:
    • In first array, iterate from LCA node value and increase count until value of node A is found, which is dist (LCA, A).
    • In the second array, iterate from LCA node value and increase count until value of node B is found, which is dist (LCA, B)
  5. Return the sum of those distances i.e dist (LCA, A) + dist (LCA, B).

C++




// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Structure of Node
struct Node {
    int val;
    vector<Node*> child;
};
 
// Utility function to create a
// new tree node
Node* newNode(int key)
{
    Node* temp = new Node;
    temp->val = key;
    return temp;
}
 
bool flag;
 
// Function to get the path
// from root to a node
void findPath(Node* root, int key,
              vector<int>& arr)
{
    if (!root)
        return;
    arr.push_back(root->val);
    // if key is found set flag and return
    if (root->val == key) {
        flag = 1;
        return;
    }
    // recur for all children
    for (int i = 0; i < root->child.size(); i++) {
 
        findPath(root->child[i], key, arr);
 
        // if key is found dont need to pop values
        if (flag == 1)
            return;
    }
 
    arr.pop_back();
    return;
}
 
void findMinDist(Node* root, int A, int B)
{
    if (root == NULL)
        return;
    int val = root->val;
 
    // vector to store both paths
    vector<int> arr1, arr2;
 
    // set flag as false;
    flag = false;
 
    // find path from root to node a
    findPath(root, A, arr1);
 
    // set flag again as false;
    flag = false;
 
    // find path from root to node b
    findPath(root, B, arr2);
 
    // to store index of LCA node
    int j;
 
    // if unequal values are found
    // return previous value
    for (int i = 1; i < min(arr1.size(), arr2.size()); i++) {
        if (arr1[i] != arr2[i]) {
            val = arr1[i - 1];
            j = i - 1;
            break;
        }
    }
    int d1 = 0, d2 = 0;
 
    // iterate for finding distance
    // between LCA(a, b) and a
    for (int i = j; i < arr1.size(); i++)
        if (arr1[i] == A)
            break;
        else
            d1 += 1;
 
    // iterate for finding distance
    // between LCA(a, b) and b
    for (int i = j; i < arr2.size(); i++)
        if (arr2[i] == B)
            break;
        else
            d2 += 1;
    // get distance
    val = d1 + d2;
    cout << val << '\n';
}
 
// Driver Code
int main()
 
{
    Node* root = newNode(1);
    (root->child).push_back(newNode(2));
    (root->child).push_back(newNode(3));
    (root->child[0]->child).push_back(newNode(4));
    (root->child[0]->child).push_back(newNode(5));
    (root->child[1]->child).push_back(newNode(6));
    (root->child[1])->child.push_back(newNode(7));
    (root->child[1]->child).push_back(newNode(8));
    int A = 4, B = 3;
 
    // get min distance
    findMinDist(root, A, B);
 
    return 0;
}


Java




// Java program for the above approach
import java.util.*;
public class Main
{
    // Structure of Node
    static class Node {
         
        public int val;
        public Node left, right;
        public Vector<Node> child;
         
        public Node(int key)
        {
            val = key;
            left = right = null;
            child = new Vector<Node>();
        }
    }
     
    // Utility function to create a
    // new tree node
    static Node newNode(int key)
    {
        Node temp = new Node(key);
        return temp;
    }
      
    static int flag;
      
    // Function to get the path
    // from root to a node
    static void findPath(Node root, int key,
                  Vector<Integer> arr)
    {
        if (root==null)
            return;
        arr.add(root.val);
        // if key is found set flag and return
        if (root.val == key) {
            flag = 1;
            return;
        }
        // recur for all children
        for (int i = 0; i < root.child.size(); i++) {
      
            findPath(root.child.get(i), key, arr);
      
            // if key is found dont need to pop values
            if (flag == 1)
                return;
        }
      
        arr.remove(arr.size()-1);
        return;
    }
      
    static void findMinDist(Node root, int A, int B)
    {
        if (root == null)
            return;
        int val = root.val;
      
        // vector to store both paths
        Vector<Integer> arr1 = new Vector<Integer>();
        Vector<Integer> arr2 = new Vector<Integer>();
      
        // set flag as false;
        flag = 0;
      
        // find path from root to node a
        findPath(root, A, arr1);
      
        // set flag again as false;
        flag = 0;
      
        // find path from root to node b
        findPath(root, B, arr2);
      
        // to store index of LCA node
        int j=0;
      
        // if unequal values are found
        // return previous value
        for (int i = 1; i < Math.min(arr1.size(), arr2.size()); i++) {
            if (arr1.get(i) != arr2.get(i)) {
                val = arr1.get(i - 1);
                j = i - 1;
                break;
            }
        }
        int d1 = 0, d2 = 0;
      
        // iterate for finding distance
        // between LCA(a, b) and a
        for (int i = j; i < arr1.size(); i++)
            if (arr1.get(i) == A)
                break;
            else
                d1 += 1;
      
        // iterate for finding distance
        // between LCA(a, b) and b
        for (int i = j; i < arr2.size(); i++)
            if (arr2.get(i) == B)
                break;
            else
                d2 += 1;
        // get distance
        val = d1 + d2;
        System.out.println(val);
    }
     
    public static void main(String[] args) {
        Node root = newNode(1);
        (root.child).add(newNode(2));
        (root.child).add(newNode(3));
        (root.child.get(0).child).add(newNode(4));
        (root.child.get(0).child).add(newNode(5));
        (root.child.get(1).child).add(newNode(6));
        (root.child.get(1)).child.add(newNode(7));
        (root.child.get(1).child).add(newNode(8));
        int A = 4, B = 3;
      
        // get min distance
        findMinDist(root, A, B);
    }
}
 
// This code is contributed by mukesh07.


Python3




# Python3 program for the above approach
 
# Structure of Node
class Node:
    def __init__(self, key):
        self.val = key
        self.left = None
        self.right = None
        self.child = []
 
# Utility function to create a
# new tree node
def newNode(key):
    temp = Node(key)
    return temp
 
flag = 0
 
# Function to get the path
# from root to a node
def findPath(root, key, arr):
    global flag
    if (root==None):
        return
    arr.append(root.val)
    # if key is found set flag and return
    if (root.val == key):
        flag = 1
        return
    # recur for all children
    for i in range(len(root.child)):
        findPath(root.child[i], key, arr)
 
        # if key is found dont need to pop values
        if (flag == 1):
            return
 
    arr.pop()
    return
 
def findMinDist(root, A, B):
    global flag
    if (root == None):
        return
    val = root.val
 
    # vector to store both paths
    arr1 = []
    arr2 = []
 
    # set flag as false;
    flag = 0
 
    # find path from root to node a
    findPath(root, A, arr1)
 
    # set flag again as false;
    flag = 0
 
    # find path from root to node b
    findPath(root, B, arr2)
 
    # to store index of LCA node
    j=0
 
    # if unequal values are found
    # return previous value
    for i in range(min(len(arr1), len(arr2))):
        if (arr1[i] != arr2[i]):
            val = arr1[i - 1]
            j = i - 1
            break
    d1, d2 = 0, 0
 
    # iterate for finding distance
    # between LCA(a, b) and a
    for i in range(j, len(arr1)):
        if (arr1[i] == A):
            break
        else:
            d1 += 1
 
    # iterate for finding distance
    # between LCA(a, b) and b
    for i in range(j, len(arr2)):
        if (arr2[i] == B):
            break
        else:
            d2 += 1
    # get distance
    val = d1 + d2
    print(val)
 
root = newNode(1)
(root.child).append(newNode(2))
(root.child).append(newNode(3))
(root.child[0].child).append(newNode(4))
(root.child[0].child).append(newNode(5))
(root.child[1].child).append(newNode(6))
(root.child[1]).child.append(newNode(7))
(root.child[1].child).append(newNode(8))
A, B = 4, 3
 
# get min distance
findMinDist(root, A, B)
 
# This code is contributed by rameshtravel07.


C#




// C# program for the above approach
using System;
using System.Collections.Generic;
 
// Structure of Node
class GFG{
 
    public class Node {
        public int val;
        public Node left=null, right=null;
        public List<Node> child = new List<Node>();
    }
 
// Utility function to create a
// new tree node
static Node newNode(int key)
{
    Node temp = new Node();
    temp.val = key;
    return temp;
}
 
static int flag;
 
// Function to get the path
// from root to a node
static void findPath(Node root, int key,
              List<int> arr)
{
    if (root==null)
        return;
    arr.Add(root.val);
    // if key is found set flag and return
    if (root.val == key) {
        flag = 1;
        return;
    }
    // recur for all children
    for (int i = 0; i < root.child.Count; i++) {
 
        findPath(root.child[i], key, arr);
 
        // if key is found dont need to pop values
        if (flag == 1)
            return;
    }
 
    arr.RemoveAt(arr.Count-1);
    return;
}
 
static void findMinDist(Node root, int A, int B)
{
    if (root == null)
        return;
    int val = root.val;
 
    // vector to store both paths
    List<int> arr1 = new List<int>();
    List<int> arr2 = new List<int>();
 
    // set flag as false;
    flag = 0;
 
    // find path from root to node a
    findPath(root, A, arr1);
 
    // set flag again as false;
    flag = 0;
 
    // find path from root to node b
    findPath(root, B, arr2);
 
    // to store index of LCA node
    int j=0;
 
    // if unequal values are found
    // return previous value
    for (int i = 1; i < Math.Min(arr1.Count, arr2.Count); i++) {
        if (arr1[i] != arr2[i]) {
            val = arr1[i - 1];
            j = i - 1;
            break;
        }
    }
    int d1 = 0, d2 = 0;
 
    // iterate for finding distance
    // between LCA(a, b) and a
    for (int i = j; i < arr1.Count; i++)
        if (arr1[i] == A)
            break;
        else
            d1 += 1;
 
    // iterate for finding distance
    // between LCA(a, b) and b
    for (int i = j; i < arr2.Count; i++)
        if (arr2[i] == B)
            break;
        else
            d2 += 1;
    // get distance
    val = d1 + d2;
    Console.WriteLine(val);
}
 
// Driver Code
public static void Main()
 
{
    Node root = newNode(1);
    (root.child).Add(newNode(2));
    (root.child).Add(newNode(3));
    (root.child[0].child).Add(newNode(4));
    (root.child[0].child).Add(newNode(5));
    (root.child[1].child).Add(newNode(6));
    (root.child[1]).child.Add(newNode(7));
    (root.child[1].child).Add(newNode(8));
    int A = 4, B = 3;
 
    // get min distance
    findMinDist(root, A, B);
}
}
 
// This code is contributed by SURENDRA_GANGWAR.


Javascript




<script>
    // Javascript program for the above approach
     
    // Structure of Node
    class Node
    {
        constructor(key) {
           this.left = null;
           this.right = null;
           this.val = key;
           this.child = [];
        }
    }
     
    // Utility function to create a
    // new tree node
    function newNode(key)
    {
        let temp = new Node(key);
        return temp;
    }
 
    let flag;
 
    // Function to get the path
    // from root to a node
    function findPath(root, key, arr)
    {
        if (root==null)
            return;
        arr.push(root.val);
        // if key is found set flag and return
        if (root.val == key) {
            flag = 1;
            return;
        }
        // recur for all children
        for (let i = 0; i < root.child.length; i++) {
 
            findPath(root.child[i], key, arr);
 
            // if key is found dont need to pop values
            if (flag == 1)
                return;
        }
 
        arr.pop();
        return;
    }
 
    function findMinDist(root, A, B)
    {
        if (root == null)
            return;
        let val = root.val;
 
        // vector to store both paths
        let arr1 = [];
        let arr2 = [];
 
        // set flag as false;
        flag = 0;
 
        // find path from root to node a
        findPath(root, A, arr1);
 
        // set flag again as false;
        flag = 0;
 
        // find path from root to node b
        findPath(root, B, arr2);
 
        // to store index of LCA node
        let j=0;
 
        // if unequal values are found
        // return previous value
        for (let i = 1; i < Math.min(arr1.length, arr2.length); i++) {
            if (arr1[i] != arr2[i]) {
                val = arr1[i - 1];
                j = i - 1;
                break;
            }
        }
        let d1 = 0, d2 = 0;
 
        // iterate for finding distance
        // between LCA(a, b) and a
        for (let i = j; i < arr1.length; i++)
            if (arr1[i] == A)
                break;
            else
                d1 += 1;
 
        // iterate for finding distance
        // between LCA(a, b) and b
        for (let i = j; i < arr2.length; i++)
            if (arr2[i] == B)
                break;
            else
                d2 += 1;
        // get distance
        val = d1 + d2;
        document.write(val);
    }
     
    let root = newNode(1);
    (root.child).push(newNode(2));
    (root.child).push(newNode(3));
    (root.child[0].child).push(newNode(4));
    (root.child[0].child).push(newNode(5));
    (root.child[1].child).push(newNode(6));
    (root.child[1]).child.push(newNode(7));
    (root.child[1].child).push(newNode(8));
    let A = 4, B = 3;
  
    // get min distance
    findMinDist(root, A, B);
 
// This code is contributed by decode2207.
</script>


Output

3

Time complexity: O(N).
Auxiliary Space: O(N).



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads