持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第20天,点击查看活动详情
今天,我们继续搞算法。
题目描述
给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。
百度百科中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”
题目分析
这个题目是给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。
最近公共祖先,首先理解题意,祖先就是根和子之间的关系,如果左右两个子同根,说明有最近公共祖先,还要满足这个子是我们输入的就可以了。
那怎么来找呢?我们使用深度优先遍历,把输入的根的所有子找出来,然后在回溯,如果当前左子或者右子是p,说明当前根是p的祖先或者是p的本身,那么同理我们可以找到q的祖先,如果条件同时满足,且最近公共祖先还没有找到,我们就更新答案,如果找到了,说明剩下的公共祖先不是最近公共祖先,就不更新,直到程序停止。
解题思路
- 确定操作对象:本题中,操作对象1个root,p和q
- 确定操作条件:解析时。如果当前根是p的祖先,又是q的祖先,而且祖先还没找到我们就更新答案
- 确定操作过程:操作过程就是深度优先遍历找p和q。
- 确定结果返回:返回最终结果。
代码
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
/**
* 这个题是让我们求这个最近公共祖先,那我们怎么来思考呢?
* 我拿示例给大家演示一下。示例1是 输入root为 :root = [3,5,1,6,2,0,8,null,null,7,4] ,然后我们找p和q的最近公共祖先,我们用深度优先遍历找3的下一层是5,1刚好是p,q,那就把3返回 。
*/
class Solution {
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
this-> p =p;
this -> q =q;
dfs(root);
return ans;
}
private:
TreeNode* p;
TreeNode* q;
TreeNode* ans;
pair<bool,bool> dfs(TreeNode* root){
if(root == nullptr) return {false,false};
pair<bool ,bool> leftResult = dfs(root -> left);
pair<bool, bool> rightResult = dfs(root -> right);
pair<bool ,bool> resullt;
resullt.first = leftResult.first || rightResult.first || root->val == p->val;
resullt.second = leftResult.second || rightResult.second || root->val == q->val;
if( resullt.first && resullt.second && ans == nullptr) ans =root;
return resullt;
}
};
、