Skip to content

题目链接 · 灵神原题解(署名来源)

视频讲解

请看【基础算法精讲 12】,制作不易,欢迎点赞!

晕递归的同学请先看 深刻理解递归

236.png

答疑

lowestCommonAncestor 函数的返回值是什么意思?

:返回值的准确含义是「最近公共祖先的候选项」。对于最外层的递归调用者来说,返回值是最近公共祖先的意思。但是,在递归过程中,返回值可能是最近公共祖先,也可能是空节点(表示子树内没找到任何有用信息)、节点 p 或者节点 q(可能成为最近公共祖先,或者用来辅助判断上面的某个节点是否为最近公共祖先)。

:为什么发现当前节点是 p 或者 q 就不再往下递归了?万一下面有 q 或者 p 呢?

:如果下面有 q 或者 p,那么当前节点就是最近公共祖先,直接返回当前节点。如果下面没有,那既然都没有要找的节点了,也不需要递归,直接返回当前节点。(注意题目保证 pq 都在二叉树中)

python
class Solution:
    def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
        if root in (None, p, q):  # 找到 p 或 q 就不往下递归了,原因见上面答疑
            return root
        left = self.lowestCommonAncestor(root.left, p, q)
        right = self.lowestCommonAncestor(root.right, p, q)
        if left and right:  # 左右都找到
            return root  # 当前节点是最近公共祖先
        # 如果只有左子树找到,就返回左子树的返回值
        # 如果只有右子树找到,就返回右子树的返回值
        # 如果左右子树都没有找到,就返回 None(注意此时 right = None)
        return left or right
cpp
// C++ 版待补充
cpp
class Solution {
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        if (root == nullptr || root == p || root == q) {
            return root; // 找到 p 或 q 就不往下递归了,原因见上面答疑
        }
        TreeNode* left = lowestCommonAncestor(root->left, p, q);
        TreeNode* right = lowestCommonAncestor(root->right, p, q);
        if (left && right) { // 左右都找到
            return root; // 当前节点是最近公共祖先
        }
        // 如果只有左子树找到,就返回左子树的返回值
        // 如果只有右子树找到,就返回右子树的返回值
        // 如果左右子树都没有找到,就返回 nullptr(注意此时 right = nullptr)
        return left ? left : right;
    }
};

复杂度分析

  • 时间复杂度:O(n),其中 n 为二叉树的节点个数。
  • 空间复杂度:O(n)。最坏情况下,二叉树是一条链,因此递归需要 O(n) 的栈空间。

分类题单

如何科学刷题?

  1. 滑动窗口与双指针(定长/不定长/单序列/双序列/三指针/分组循环)
  2. 二分算法(二分答案/最小化最大值/最大化最小值/第K小)
  3. 单调栈(基础/矩形面积/贡献法/最小字典序)
  4. 网格图(DFS/BFS/综合应用)
  5. 位运算(基础/性质/拆位/试填/恒等式/思维)
  6. 图论算法(DFS/BFS/拓扑排序/基环树/最短路/最小生成树/网络流)
  7. 动态规划(入门/背包/划分/状态机/区间/状压/数位/数据结构优化/树形/博弈/概率期望)
  8. 常用数据结构(前缀和/差分/栈/队列/堆/字典树/并查集/树状数组/线段树)
  9. 数学算法(数论/组合/概率期望/博弈/计算几何/随机算法)
  10. 贪心与思维(基本贪心策略/反悔/区间/字典序/数学/思维/脑筋急转弯/构造)
  11. 链表、二叉树与回溯(前后指针/快慢指针/DFS/BFS/直径/LCA/一般树)
  12. 字符串(KMP/Z函数/Manacher/字符串哈希/AC自动机/后缀数组/子序列自动机)

我的题解精选(已分类)

欢迎关注 B站@灵茶山艾府

本文整理自灵茶山艾府(endlesscheng)的公开内容,仅供个人学习使用

本站仅供个人学习使用,请勿外传