Min distance between two given nodes of a Binary Tree | Practice | GeeksforGeeks

Given a binary tree and two node values your task is to find the minimum distance between them.
Example 1:
Input:
        1
      /  \
     2    3
a = 2, b = 3
Output: 2
Explanation: The tree formed is:
       1
     /   \ 
    2     3
We need the distance between 2 and 3.
Being at node 2, we need to take two
steps ahead in order to reach node 3.
The path followed will be:
2 -> 1 -> 3. Hence, the result is 2. 
Your Task:
You don't need to read input or print anything. Your task is to complete the function findDist() which takes the root node of the Tree and the two node values a and b as input parameters and returns the minimum distance between the nodes represented by the two given node values.
Expected Time Complexity: O(N).
Expected Auxiliary Space: O(Height of the Tree).
Constraints:
1 <= Number of nodes <= 104
1 <= Data of a node <= 105



Note:The Input/Ouput format and Example given are used for system's internal purpose, and should be used by a user for Expected Output only. As it is a function problem, hence a user should not read any input from stdin/console. The task is to complete the function specified, and not to write the full code.
0
tirtha19025681 week ago
class GfG {
   int findDist(Node root, int a, int b) {
       int ans = distance(root,a,b);
       return ans;
   }
   
    int distance(Node root,int a,int b) {
 if(root == null) return 0;
 Node lca = lca(root,a,b);
 if(lca == null) return 0;
 int ans = helper(lca,a,b);
 
 return ans;
}

 int helper(Node lca,int a,int b) {
 // dist b/w  : (a - lca) + (b - lca)
 int cnt1 = 0;
 int cnt2 = 0;
 cnt1 = dist(lca,a);
 cnt2 = dist(lca,b);
 
 return cnt1 + cnt2;
}

 int dist(Node root, int x)
{
    // Base case
    if (root == null)
    return -1;
 
    // Initialize distance
    int dist = -1;
 
    // Check if x is present at root or in left
    // subtree or right subtree.
    if ((root.data == x) ||
        (dist = dist(root.left, x)) >= 0 ||
        (dist = dist(root.right, x)) >= 0)
        return dist + 1;
 
    return dist;
}

 Node lca(Node root,int a,int b) {
 if(root == null) return null;
 if(root.data == a || root.data == b) return root;
 
 Node left = lca(root.left,a,b);
 Node right = lca(root.right,a,b);
 
 if(left == null) return right;
 else if(right == null) return left;
 
 else return root;
}

   
}
0
ajaysingh74181 week ago
simple same logic as LCA 
 
bool fill_path(Node* root , vector<int> &path , int n)   {       if(root == NULL)       return false;              path.push_back(root->data);              if(root->data == n)       return true;              if(fill_path(root->left , path , n) || fill_path(root->right , path , n))       {           return true;       }              path.pop_back();              return false;          }   int findDist(Node* root, int a, int b) {       // Your code here       vector<int> path1;       vector<int> path2;              fill_path(root , path1 , a);       fill_path(root , path2 , b);              int ans = 0;             path1.resize(100 , 0);       path2.resize(100 , 0);              for(int i = 0; i < path1.size() && path2.size(); i ++)       {           if(path1[i] == 0 && path2[i] != 0)           ans ++;           else if(path1[i] != 0 && path2[i] == 0)           ans ++;           else if(path1[i] != path2[i])           ans += 2;                      if(path1[i] == 0 && path2[i] == 0)           break;       }              if(ans == 0)return 1;              return ans;                 }
+3
goswamikrunal85718652 weeks ago
The updated version of the code: It will work for sure:)
Please give an upvote if you liked the approach.
Same common ancestor approach, but to avoid duplicate values and get the nearest value of LCA, changed the logic in solve part.

class Solution{
   Node* leastCommonAncestor(Node* root, int a, int b){
       if(!root) return NULL;
       if(root->data==a or root->data==b) return root;
       Node* l = leastCommonAncestor(root->left, a, b);
       Node* r = leastCommonAncestor(root->right, a, b);
       
       if(l and r) return root;
       if(l) return l;
       return r;
   }
   int solve(Node* root, int a){
       if(!root) return 0;
       if(root->data == a) return 1;
       int l = solve(root->left, a);
       int r = solve(root->right, a);
       if(!l and !r) return 0;
       if(!l) return r+1;
       if(!r) return l+1;
       int minVal = min(l,r);
       return minVal +1;
   }
   public:
   /* Should return minimum distance between a and b
   in a tree with given root*/
   int findDist(Node* root, int a, int b) {
       // Your code here
       Node* lca = leastCommonAncestor(root, a, b);
       int x = solve(lca, a);
       int y = solve(lca, b);
       return (x + y - 2);
   }
};
 
+1
upadhyayabhi01072 weeks ago
class Solution{
    public:
    Node* lca(Node* root , int a , int b){
        if(!root) return nullptr;
        if(root->data == a || root->data == b){
            return root;
        }
        Node* lst = lca(root->left , a , b);
        Node* rst = lca(root->right , a , b);
        if(!lst) return rst;
        if(!rst) return lst;
        return root;
    }
    void traverse(Node* root , Node* ancestor , int a , int b , int& l1 , int &l2 , int& l3 , int level){
        if(root){
            if(root->data == ancestor->data && l1 == -1){
                l1 = level;
            }
            if(root->data == a && l2 == -1){
                l2 = level;
            }
            if(root->data == b && l3 == -1){
                l3 = level;
            }
            traverse(root->left , ancestor , a , b , l1 , l2 , l3 , level + 1);
            traverse(root->right , ancestor , a , b , l1 , l2 , l3 , level + 1);
        }
    }
    int findDist(Node* root, int a, int b) {
        Node* ancestor = lca(root , a , b);
        int l1 = -1 , l2 = -1 , l3 = -1;
        traverse(root , ancestor  , a , b , l1 , l2 , l3 , 0);
        return (l3 + l2 - 2 * l1);
    }
};
0
upadhyayabhi0107
This comment was deleted.
-1
apurvkumarak3 weeks ago
C++ Solution 
    bool route(Node * node,int goal,vector<int> & vec){
        if(node != NULL){
            vec.push_back(node->data);
            if(node->data==goal){
                return true;
            }
            bool res1=route(node->left,goal,vec);
            if(res1){
                return true;
            }
            bool res2=route(node->right,goal,vec);
            if(res2){
                return true;
            }
            vec.pop_back();
        }
        return false;
    }
    int findDist(Node* root, int a, int b) {
        vector<int> r1;
        route(root,a,r1);
        vector<int> r2;
        route(root,b,r2);
        unordered_map<int,int> mp,mp1;
        for(auto v:r1){
            mp[v]++;
        }
        for(auto v:r2){
            mp[v]++;
        }
        for(int i=r1.size()-1;i >=0;i--){
            if(mp[r1[i]] > 1){
                mp1[r1[i]]=r1.size()-i-1;
            }
        }
        int res=INT_MAX;
        for(int i=r2.size()-1;i >=0;i--){
            if(mp[r2[i]] > 1){
                int temp=r2.size()-i-1+mp1[r2[i]];
                res=std::min(res,temp);
            }
        }
        return res;
    }
0
6288264 weeks ago
Base on the observation that 
    path(a→b) equals to 
    path(root→a) + path(root→b) - 2 * path(root→lowest_common_ancestor(a, b))
Happy coding.
bool find(Node* root, int x, vector<int> &path)
{
	if (! root)
		return false;
		
	if (root->data == x)
		return true;
		
	path.push_back(0);
	
	if (find(root->left, x, path))
		return true;
		
	path.back() = 1;
	
	if (find(root->right, x, path))
		return true;
		
	path.pop_back();
	return false;
}

int findDist(Node* root, int a, int b) {
	vector<int> pa, pb;
	
	find(root, a, pa);
	find(root, b, pb);
	
	int r = pa.size() + pb.size();
	
	for (int i = 0; 
		i < pa.size() && i < pb.size() && pa[i] == pb[i]; 
		++i, r -= 2)
	;
	
	return r;
}
0
0166621m4 weeks ago
class Solution{
    int res,x,y;
    int func(Node* root, int a, int b,int len=0)
    {
        if(root==NULL)
        return -1;
        
        int l=func(root->left,a,b,len+1), r = func(root->right,a,b,len+1);
        if(root->data == a)
        {
            if(l==2)
            {
                
                res = y-len;
                return -1;
            }
            if(r==2)
            {
                res = y - len;
                return -1;
            }
            x=len;
            // cout<<root->data<<" "<<len<<endl;
            return 1;
        }
        if(root->data == b)
        {
            if(l==1)
            {
                res = x-len;
                return -1;
            }
            if(r==1)
            {
                res = x - len;
                return -1;
            }
            // cout<<root->data<<" "<<len<<endl;
            y=len;
            return 2;
        }
        
        if(l+r == 3)
        {
            res = x-len + y-len;
            return -1;
        }
        if(l!=-1)
        return l;
        return r;
    }
    public:
    /* Should return minimum distance between a and b
    in a tree with given root*/
    int findDist(Node* root, int a, int b) {
        // Your code here
        res=x=y=0;
        func(root,a,b);
        return res;
    }
};
+1
satyamagarwal2491 month ago
class Solution:
    
    def findDist(self,root,a,b):
        self.visit =[False, False]
        self.ans= None
        ans = self.LCA(root, a, b)
        if self.visit[0] and self.visit[1]:
            return self.ans
        elif self.visit[0]:
            return self.find(root, b) - ans 
        elif self.visit[1]:
            return self.find(root, a) - ans 
        return None
    
    def find(self, root, key):
        if root is None:
            return None
        if root.data ==  key:
            return 1
        l = self.find(root.left, key)
        if l  is not None:
            return l + 1
        r = self.find(root.right, key)
        if r  is not None:
            return r + 1
        return None
            
        
    
    def LCA(self, root, a, b):
        if root is None:
            return None
        if root.data == a:
            self.visit[0] = True
            return 1
        if root.data == b:
            self.visit[1] = True
            return 1
        
        l = self.LCA(root.left, a, b)
        r = self.LCA(root.right, a, b)
        
        if l is not None and r is not None :
            self.ans = l + r
            return l + r
        elif l is not None:
            return 1 + l
        elif r is not None:
            return 1 + r
        else:
            return None
        
0
abrajput15061 month ago
void helper(Node* root,int a,int b,int &mn,
                int &levelA,int &levelB,int level,Node* lca){
        if(!root)
            return;
        
        if(root->data == a && levelA == -1)
            levelA = level;
        if(root->data == b && levelB == -1)
            levelB = level;
         
            
        helper(root->left,a,b,mn,levelA,levelB,level+1,lca);
        helper(root->right,a,b,mn,levelA,levelB,level+1,lca);    
        
        if(levelA != -1 && levelB != -1 && lca == root){
                mn = abs(levelA-level)+abs(levelB-level);
                
        }
        
    }
    Node* lca(Node* root, int a, int b){
        if(!root)
            return root;
        if(root->data == a || root->data == b)
            return root;
        
        Node* left = lca(root->left,a,b);
        Node* right = lca(root->right,a,b);
        
        if(left && right) return root;
        return left ? left : right;
    }
    int findDist(Node* root, int a, int b) {
        // Your code here
        int mn  = INT_MAX,levelA = -1,levelB = -1,level = 0;
        helper(root,a,b,mn,levelA,levelB,0,lca(root,a,b));
        return mn;
    }
We strongly recommend solving this problem on your own before viewing its editorial. Do you still
                    want to view the editorial?
 Login to access your submissions. 

Problem


Contest

Reset the IDE using the second button on the top right corner.
Avoid using static/global variables in your code as your code is tested against multiple test cases and these tend to retain their previous values.
Passing the Sample/Custom Test cases does not guarantee the correctness of code. On submission, your code is tested against multiple test cases consisting of all possible corner cases and stress constraints.
You can access the hints to get an idea about what is expected of you as well as the final solution code.
You can view the solutions submitted by other users from the submission tab.