236. 二叉树的最近公共祖先C++

链接:

https://leetcode.cn/problems/lowest-common-ancestor-of-a-binary-tree/

描述:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

代码:

代码一:

遍历二叉树
判断这个节点的左边是否有pq,或者右边是否有pq
然后进入左边或者右边
一直到pq一个在左,一个在右

class Solution {
public:
	bool Find(TreeNode* root, TreeNode* x) {
		if (root == nullptr) return false;
		if (root == x) return true;
		return Find(root->left, x) || Find(root->right, x);
	}

	TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
		if (root == nullptr) return nullptr;
		if (root == p || root == q) return root;

		bool PInleft, PInright, QInleft, QInright;
		PInleft = Find(root->left, p);
		PInright = !PInleft;

		QInleft = Find(root->left, q);
		QInright = !QInleft;

		if ((PInleft && QInright) || (QInleft && PInright)) {
			return root;
		}
		else if (PInleft && QInleft)
			return lowestCommonAncestor(root->left, p, q);
		else if (PInright && QInright)
			return lowestCommonAncestor(root->right, p, q);

		return nullptr;
	}
};

代码二:

分别求出pq的路径(从根节点到pq的)
然后找到两个路径的交点
提示:栈

class Solution {
public:
    bool FindPath(TreeNode* root,TreeNode* x,stack<TreeNode*>& path){
        if(root==NULL) return false;
        path.push(root);
        if(root==x) return true;

        if(FindPath(root->left,x,path))return true;
        if(FindPath(root->right,x,path))return true;

        path.pop();
        return false;
    }
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        stack<TreeNode*> Ppath,Qpath;
        FindPath(root,p,Ppath);
        FindPath(root,q,Qpath); 

        while(Ppath.size()!=Qpath.size()){
            if(Ppath.size()>Qpath.size())
                Ppath.pop();
            else Qpath.pop();
        }

        while(Ppath.top()!=Qpath.top())
        {
            Ppath.pop();
            Qpath.pop();
        }
        return Ppath.top();
    }
};

延伸:

如果是 搜索树
1.一个比我小,一个比我大,那么我就是最近祖先
2.都比我大,去右树递归查找
3.都比我小,去左数递归查找

常见问题

代码一的最后一行的
return nullptr;

编译器会有语法检查
我们可以理解不会执行到最后一行的 return nullptr
如果执行到这里就是出错了

但是编译器会检查
万一运行到这里怎么办?
所以要加上这一行代码

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值