面向小白的力扣236. 二叉树的最近公共祖先-dfs

119 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 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;
          }
};

、