代码随想录算法训练营第30天|LeetCode236.二叉树的最小公共祖先
1、LeetCode236.二叉树的最小公共祖先
236. 二叉树的最近公共祖先 - 力扣(LeetCode)
自底向上查找,有点难度! | LeetCode:236. 二叉树的最近公共祖先_哔哩哔哩_bilibili
没啥想法。是彻底地不会写。
思路
找到了两个节点p,q,那么往上遍历,找到交汇节点即最小公共祖先。
Q:入口是根节点,那么如何从下往上遍历呢?
A:遍历顺序是从上往下,但是处理顺序可以是从下往上。——回溯,从底往上处理结果。后序遍历。
情况
情况1:
节点分别在左右子树。
- 左子树只要出现了P,Q,往上返回,右子树同。(这样不会出现左右都是p的情况吗?不会,因为题目中说了二叉树的值不重复)
- 左右都不为空,那么中就是最小公共祖先。
情况2:
节点本身就是祖先。
情况1包括了情况2。
递归三部曲
- 函数参数和返回值:传递根节点,p,q;返回p,q的最小公共祖先。
- 终止情况
- root为空,返回空
- 若是p或q,返回root
- 单层逻辑
- 左:左子树是否出现了p或q
- 右
- 中
- 左不空,右不空。返回root。
- 左空,右不空。返沪右
- 左不空,右空。返回左
- 左右都空,返回NULL
如何包含情况2?若root为p或q,直接返回root了,没有遍历root以下的树。
代码
class Solution {
public:TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {// 终止条件if(root == NULL)return NULL;if(root == p || root == q)return root;// 单层逻辑TreeNode* left = lowestCommonAncestor(root->left, p, q);TreeNode* right = lowestCommonAncestor(root->right, p, q);if(left && right)return root;else if(left == NULL && right)return right;else if(left && right==NULL)return left;elsereturn NULL;}
};