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:
- Find path from root node to the nodes A and B, respectively and simultaneously store the two paths in two arrays.
- Now iterate until values of both the arrays are same and value just before mismatch is the LCA node value.
- The value just before mismatch is the LCA node value.
- 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)
- Return the sum of those distances i.e dist (LCA, A) + dist (LCA, B).
// 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 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 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# 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. |
<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> |
3
Time complexity: O(N).
Auxiliary Space: O(N).