zoukankan      html  css  js  c++  java
  • 236. Lowest Common Ancestor of a Binary Tree

    leetcode链接

    题目

    给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。

    方法

    我们递归遍历整棵二叉树,定义 fx 表示 x节点的子树中是否包含 p节点或 q节点,如果包含为 true,否则为 false。

    那么符合条件的最近公共祖先 x 一定满足如下条件:

    (flson && frson) || ( (x=p || x=q) && (flson || frson) )

    其中 lson 和 rson 分别代表 x 节点的左孩子和右孩子。初看可能会感觉条件判断有点复杂,我们来一条条看,flson && frson 说明左子树和右子树均包含 p 节点或 q 节点,如果左子树包含的是 p 节点,那么右子树只能包含 q 节点,反之亦然,因为 p 节点和 q 节点都是不同且唯一的节点,因此如果满足这个判断条件即可说明 x 就是我们要找的最近公共祖先。再来看第二条判断条件,这个判断条件即是考虑了 x 恰好是 p 节点或 q 节点且它的左子树或右子树有一个包含了另一个节点的情况,因此如果满足这个判断条件亦可说明 x 就是我们要找的最近公共祖先。

    你可能会疑惑这样找出来的公共祖先深度是否是最大的。其实是最大的,因为我们是自底向上从叶子节点开始更新的,所以在所有满足条件的公共祖先中一定是深度最大的祖先先被访问到,且由于 fx 本身的定义很巧妙,在找到最近公共祖先 x 以后, fx 按定义被设置为 true ,即假定了这个子树中只有一个 p 节点或 q 节点,因此其他公共祖先不会再被判断为符合条件。

    代码

    class Solution {
    public:
        TreeNode* ans;
        bool dfs(TreeNode* root, TreeNode* p, TreeNode* q) {
            if (root == nullptr) return false;
            bool lson = dfs(root->left, p, q);
            bool rson = dfs(root->right, p, q);
            if ((lson && rson) || ((root->val == p->val || root->val == q->val) && (lson || rson))) {
                ans = root;
            } 
            return lson || rson || (root->val == p->val || root->val == q->val);
        }
        TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
            dfs(root, p, q);
            return ans;
        }
    };
    

    复杂度分析

    时间复杂度:O(N),其中 N 是二叉树的节点数。二叉树的所有节点有且只会被访问一次,因此时间复杂度为 O(N)。

    空间复杂度:O(N),其中 N 是二叉树的节点数。递归调用的栈深度取决于二叉树的高度,二叉树最坏情况下为一条链,此时高度为 N,因此空间复杂度为 O(N)。

    只有0和1的世界是简单的
  • 相关阅读:
    linux三剑客之grep
    MySQL练习(1)
    appium获取toast方法
    Could not parse UiSelector argument: 'XXX' is not a string 错误解决办法
    基于python的几种排序算法的实现
    生成allure测试报告之后,服务器端口无法访问查看生成的report,可能是这样引起的。
    通过源码看原理之 selenium
    如何查看浏览器记住的密码
    传智播客JavaWeb day09-mysql入门、数据库操作、数据库表操作、数据行操作
    SQLServer数据库表架构和数据保存成sql文件
  • 原文地址:https://www.cnblogs.com/nullxjx/p/14872624.html
Copyright © 2011-2022 走看看