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).



Previous Article
Next Article

Similar Reads

Count of nodes in a given N-ary tree having distance to all leaf nodes equal in their subtree
Given an N-ary tree root, the task is to find the number of non-leaf nodes in the tree such that all the leaf nodes in the subtree of the current node are at an equal distance from the current node. Example: Input: Tree in the below imageOutput: 4Explanation: The nodes {10, 3, 2, 4} have the distance between them and all the leaf nodes in their sub
11 min read
Count of nodes in given N-ary tree such that their subtree is a Binary Tree
Given an N-ary tree root, the task is to find the count of nodes such that their subtree is a binary tree. Example: Input: Tree in the image below Output: 11Explanation: The nodes such that there subtree is a binary tree are {2, 8, 10, 6, 7, 3, 1, 9, 5, 11, 12}. Input: Tree in the image below Output: 9 Approach: The given problem can be solved by u
11 min read
Maximum weighted edge in path between two nodes in an N-ary tree using binary lifting
Given an N-ary tree with weighted edge and Q queries where each query contains two nodes of the tree. The task is to find the maximum weighted edge in the simple path between these two nodes.Examples: Naive Approach: A simple solution is to traverse the whole tree for each query and find the path between the two nodes.Efficient Approach: The idea i
15 min read
Remove all leaf nodes from a Generic Tree or N-ary Tree
Given a Generic tree, the task is to delete the leaf nodes from the tree. Examples: Input: 5 / / \ \ 1 2 3 8 / / \ \ 15 4 5 6 Output: 5 : 1 2 3 1 : 2 : 3 : Explanation: Deleted leafs are: 8, 15, 4, 5, 6 Input: 8 / | \ 9 7 2 / | \ | / / | \ \ 4 5 6 10 11 1 2 2 3 Output: 8: 9 7 2 9: 7: 2: Approach: Follow the steps given below to solve the problem Co
9 min read
Find distance between two nodes in the given Binary tree for Q queries
Given a binary tree having N nodes and weight of N-1 edges. The distance between two nodes is the sum of the weight of edges on the path between two nodes. Each query contains two integers U and V, the task is to find the distance between nodes U and V. Examples: Input: Output: 3 5 12 12 Explanation: Distance between nodes 1 to 3 = weight(1, 3) = 2
16 min read
Minimum difference between any two weighted nodes in Sum Tree of the given Tree
Given a tree of N nodes, the task is to convert the given tree to its Sum Tree(including its own weight) and find the minimum difference between any two node's weight of the sum tree. Note: The N nodes of the given tree are given in the form of top to bottom with N-1 line where each line describes two nodes that are connected. Examples: Input: Outp
11 min read
Maximize sum of minimum difference of divisors of nodes in N-ary tree
Given a n-ary tree having nodes with a particular weight, our task is to find out the maximum sum of the minimum difference of divisors of each node from root to leaf. Examples: Input: 18 / \ 7 15 / \ \ 4 12 2 / 9 Output: 10 Explanation: The maximum sum is along the path 18 -&gt; 7 -&gt; 12 -&gt; 9 Minimum difference between divisors of 18 = 6 - 3
8 min read
Difference between sums of odd level and even level nodes in an N-ary Tree
Given an N-ary Tree rooted at 1, the task is to find the difference between the sum of nodes at the odd level and the sum of nodes at even level. Examples: Input: 4 / | \ 2 3 -5 / \ / \ -1 3 -2 6Output: 10Explanation:Sum of nodes at even levels = 2 + 3 + (-5) = 0Sum of nodes at odd levels = 4 + (-1) + 3 + (-2) + 6 = 10Hence, the required difference
9 min read
Common nodes in the inorder sequence of a tree between given two nodes in O(1) space
Given a binary tree consisting of distinct values and two numbers K1 and K2, the task is to find all nodes that lie between them in the inorder sequence of the tree. Examples: Input: 1 / \ 12 11 / / \ 3 4 13 \ / 15 9 k1 = 12 k2 = 15 Output: 1 4 Explanation: Inorder sequence is 3 12 1 4 15 11 9 13 The common nodes between 12 and 15 in the inorder se
10 min read
Construct an N-ary Tree having no pair of adjacent nodes with same weight from given weights
Given an array weights[] consisting of N positive integer, where weights[i] denotes the weight of ith node, the task is to construct an N-ary tree such that no two directly connected nodes have same weight. If it is possible to make such a tree, then print "Yes" along with their edges. Otherwise, print "No". Examples: Input: weights[] = {1 2 1 2 5}
10 min read
Practice Tags :