Find the nearest common ancestor (LCA) Apare_xzc of two nodes in the binary tree

Find the nearest common ancestor (LCA) of two nodes in the binary tree

Niu Ke topic link <–


The node definition of the tree:

struct TreeNode{
    
    
	int val;
	struct TreeNode * left;
	struct TreeNode * right;
	TreeNode(int x=0) : val(x), left(NULL), right(NULL) {
    
    }
}

Title:

Given the root node of a binary tree, the val value of each node in the data assurance tree is different. Given two values ​​O1, O2, find the val value of the nearest common ancestor node of the node where O1 and O2 are located.

Function interface requirements:

/*
* struct TreeNode{
* 	int val;
* 	struct TreeNode * left;
* 	struct TreeNode * right;
*	TreeNode(int x=0) : val(x), left(NULL), right(NULL) {}
* }
*/
class Solution {
    
    
public:
    /**
     * 
     * @param root TreeNode类 
     * @param o1 int整型 
     * @param o2 int整型 
     * @return int整型
     */
    int lowestCommonAncestor(TreeNode* root,int o1,int o2) {
    
    
    	//write code here
	}
};

Idea 1: dfs finds all ancestor nodes of O1, dfs finds all ancestor nodes of O2, and then traverses the bfs sequence, finding the last one is the ancestor of O1, and the node that is the ancestor of O2 is the answer

class Solution {
    
    
public:
    /**
     * 
     * @param root TreeNode类 
     * @param o1 int整型 
     * @param o2 int整型 
     * @return int整型
     */
    void dfs(TreeNode * now,int val,unordered_map<TreeNode*,int>& mp) {
    
    
        if(!now) return;
        if(now->val==val) {
    
     //找到了这个值 
            mp[now] = 1;
            return;
        }
        if(now->left) {
    
    
            dfs(now->left,val,mp);
            auto it = mp.find(now->left);
            if(it!=mp.end()) {
    
     //说明在左子树中 
                mp[now] = 1;
                return;
            }
        }
        if(now->right) {
    
    
            dfs(now->right,val,mp);
            auto it = mp.find(now->right);
            if(it!=mp.end()) {
    
    
                mp[now]=1;
            }
        }
    }                    
    int bfs(TreeNode * root,unordered_map<TreeNode*,int>&fo1,unordered_map<TreeNode*,int>&fo2) {
    
    
        if(!root) return -1; 
        queue<TreeNode*> Q;
        Q.push(root);
        int ans = -1;
        while(!Q.empty()) {
    
    
            TreeNode * tp = Q.front();
            Q.pop();
            if(fo1.find(tp)!=fo1.end() && fo2.find(tp)!=fo2.end()) ans = tp->val;
            if(tp->left) Q.push(tp->left);
            if(tp->right) Q.push(tp->right);
        }
        return ans;
    }
    int lowestCommonAncestor(TreeNode* root, int o1, int o2) {
    
    
        unordered_map<TreeNode*,int> fo1; //标记所有o1的祖先结点(包括它自己)
        unordered_map<TreeNode*,int> fo2; //标记所有o2的祖先结点(包括它自己)
        dfs(root,o1,fo1);
        dfs(root,o2,fo2);
        return bfs(root,fo1,fo2); 
    }
};

Idea 2: Simplicity doubles. Find the height of o1 and o2, first jump to the same height, and then jump up one by one until they meet

class Solution {
    
    
public:
    /**
     * 
     * @param root TreeNode类 
     * @param o1 int整型 
     * @param o2 int整型 
     * @return int整型
     */
    int lowestCommonAncestor(TreeNode* root,int o1,int o2) {
    
    
    	unordered_map<int,int> Height;
    	unordered_map<int,int> fa;
    	getFatherAndHeight(root,1,Height,fa);
    	int h1 = Height[o1], h2 = Height[o2];
    	while(h2>h1) o2 = fa[o2],--h2;
    	while(h2<h1) o1 = fa[o1],--h1;
		while(o2!=o1) o2 = fa[o2], o1 = fa[o1];
		return o1; 
	}
    void getFatherAndHeight(TreeNode * root,int h,unordered_map<int,int>&Height,unordered_map<int,int>& fa) {
    
    
    	if(!root) return;
    	Height[root->val] = h;
    	if(root->left) {
    
    
    		fa[root->left->val] = root->val;
    		getFatherAndHeight(root->left,h+1,Height,fa);
		}
		if(root->right) {
    
    
			fa[root->right->val] = root->val;
			getFatherAndHeight(root->right,h+1,Height,fa);
		}
	} 
};

Idea three, recursion

//201ms
class Solution {
    
    
public:
    /**
     * 
     * @param root TreeNode类 
     * @param o1 int整型 
     * @param o2 int整型 
     * @return int整型
     */
     
     TreeNode* dfs(TreeNode * root,int o1,int o2) {
    
    
         if(root==nullptr||root->val==o1||root->val==o2) return root;
         TreeNode * lans = dfs(root->left,o1,o2); 
         TreeNode * rans = dfs(root->right,o1,o2);
         if(lans==nullptr) return rans; //o1,o2都在右子树
         if(rans==nullptr) return lans; //o1,o2都在左子树
         return root; //o1,o2,左子树右子树各有一个
     }
     int lowestCommonAncestor(TreeNode* root,int o1,int o2) {
    
    
    	return dfs(root,o1,o2)->val; 
	}
 
};

Debug the code yourself

/*struct TreeNode {
	int val;
	struct TreeNode *left;
	struct TreeNode *right;
	TreeNode(int x):val(x),left(NULL),right(NULL){}
	TreeNode():left(NULL),right(NULL){} 
};*/
vector<string> vstr = {
    
    "1","2","4","#","#","5","#","#","3","6","#","#","7","#","#"}; //先序建树 
TreeNode * build(vector<string>& vstr,int& x) {
    
    
	if(vstr[x]==string("#")) {
    
    
		++x; return nullptr;		
	}  
	TreeNode * root = new TreeNode();
	istringstream ism(vstr[x++]);
	ism>>root->val;
	root->left = build(vstr,x);
	root->right = build(vstr,x);
	return root; 
}

Guess you like

Origin blog.csdn.net/qq_40531479/article/details/108742219