ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

【二叉树-11】236.二叉树的最近公共祖先

【二叉树-11】236.二叉树的最近公共祖先 题目描述给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。百度百科中最近公共祖先的定义为“对于有根树 T 的两个节点 p、q最近公共祖先表示为一个节点 x满足 x 是 p、q 的祖先且 x 的深度尽可能大一个节点也可以是它自己的祖先。”示例 1输入root [3,5,1,6,2,0,8,null,null,7,4], p 5, q 1输出3解释节点 5 和节点 1 的最近公共祖先是节点 3 。示例 2输入root [3,5,1,6,2,0,8,null,null,7,4], p 5, q 4输出5解释节点 5 和节点 4 的最近公共祖先是节点 5 。因为根据定义最近公共祖先节点可以为节点本身。示例 3输入root [1,2], p 1, q 2输出1解题思路方法递归后序遍历核心思路对于任意节点root判断 p 和 q 的位置p 和 q 都在左子树→ LCA 在左子树p 和 q 都在右子树→ LCA 在右子树p 和 q 分别在左右子树→ LCA 就是当前节点当前节点就是 p 或 q→ LCA 就是当前节点递归函数定义TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q)返回值含义如果root是 p 或 q返回root如果root的左右子树分别包含 p 和 q返回root如果root的左右子树只有一边包含 p 或 q返回那一边的结果如果都不包含返回nullptr具体过程示例3 / \ 5 1 / \ / \ 6 2 0 8 / \ 7 4 p 5, q 4 递归过程: 1. 节点3: 左子树返回5, 右子树返回null → 返回5 2. 节点5: 左子树返回null, 右子树返回4 → 返回5因为5是p 3. 节点2: 左子树返回7, 右子树返回4 → 返回2左右都非空 最终: 5 ✅代码实现class Solution { public: TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) { // 终止条件 if (root nullptr) return nullptr; if (root p || root q) return root; // 递归左右子树 TreeNode* left lowestCommonAncestor(root-left, p, q); TreeNode* right lowestCommonAncestor(root-right, p, q); // 左右都非空说明 p 和 q 分别在两侧当前节点就是 LCA if (left ! nullptr right ! nullptr) return root; // 只有一边非空返回那一边 return (left ! nullptr) ? left : right; } };复杂度分析维度复杂度说明时间复杂度O(n)最坏情况遍历所有节点空间复杂度O(h)递归栈深度h 是树的高度空间复杂度说明最坏情况链状树O(n)平均情况平衡树O(log n)关键细节1. 为什么root p || root q就返回root因为如果当前节点就是 p 或 q它可能是 LCA如果另一个在它的子树中或者它不是 LCA但需要向上传递我找到了 p 或 q这个信息2. 为什么left ! nullptr right ! nullptr时返回root因为左子树找到了 p 或 q右子树找到了另一个说明 p 和 q分别在两侧当前节点就是它们的最近公共祖先3. 为什么最后返回left ! nullptr ? left : right如果只有左子树非空说明 p 和 q都在左子树返回左子树的结果如果只有右子树非空说明 p 和 q都在右子树返回右子树的结果如果都为空返回nullptr总结要点说明核心思想后序遍历判断 p 和 q 的位置关键判断左右都非空 → 当前节点是 LCA时间复杂度O(n)空间复杂度O(h)
返回列表