在二叉树中找到两个结点的最近公共祖先(LCA) Apare_xzc

在二叉树中找到两个结点的最近公共祖先(LCA)

牛客题目链接<–


树的结点定义:

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

题意:

给定一颗二叉树的根结点,数据保证树中每个结点的val值都不同。给两个值O1, O2, 求O1所在结点 和 O2 所在结点 的最近公共祖先结点的val值。

函数接口要求:

/*
* 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
	}
};

思路一:dfs找到所有O1的祖先结点,dfs找到所有O2的祖先结点,然后bfs层序遍历,找到最后一个即为O1祖先,有为O2祖先 的结点即为答案

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); 
    }
};

思路二:朴素倍增。找到o1的高度和o2的高度,先跳到高度一样了,然后再一起一个一个往上跳,直到相遇

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);
		}
	} 
};

思路三,递归

//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; 
	}
 
};

自己调试代码

/*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; 
}

猜你喜欢

转载自blog.csdn.net/qq_40531479/article/details/108742219
今日推荐