LeetCode 236. 二叉树的最近公共祖先 | C++语言版
LeetCode 236. 二叉树的最近公共祖先
题目描述
题目地址:236. 二叉树的最近公共祖先
给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。
百度百科中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”
解题思路
思路一:使用递归
代码实现
C++
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
//表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)
//自底向上查找:使用回溯:后序遍历(左右中)就是天然的回溯过程
//在回溯的过程中,必然要遍历整棵二叉树,即使已经找到结果了,依然要把其他节点遍历完,因为要使用递归函数的返回值(也就是代码中的left和right)做逻辑判断
if (root == q || root == p || root == NULL) return root;
TreeNode* left = lowestCommonAncestor(root->left, p, q);
TreeNode* right = lowestCommonAncestor(root->right, p, q);
//如果left 和 right都不为空,说明此时root就是最近公共节点
if (left != NULL && right != NULL) return root;
//如果left为空,right不为空,就返回right,说明目标节点是通过right返回的,反之依然
if (left == NULL && right != NULL) return right;
else if (left != NULL && right == NULL) return left;
else { // (left == NULL && right == NULL)
return NULL;
}
}
};
运行结果
参考文章:
思路二:减少遍历节点数
代码实现
C++
在这里插入代码片
运行结果
参考文章:
LeetCode 剑指 Offer 68 - I. 二叉搜索树的最近公共祖先
题目描述
题目地址:剑指 Offer 68 - I. 二叉搜索树的最近公共祖先
给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。
百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”
例如,给定如下二叉搜索树: root = [6,2,8,0,4,7,9,null,null,3,5]
解题思路
思路一:使用递归
代码实现
C++
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
private:
TreeNode* traversal(TreeNode* cur,TreeNode* p,TreeNode* q){
//中
if(cur==NULL) return cur;
//左
//如果 cur->val 大于 p->val,同时 cur->val 大于q->val,那么就应该向左遍历(说明目标区间在左子树上)
if(cur->val>p->val && cur->val>q->val){
TreeNode* left=traversal(cur->left,p,q);
if(left!=NULL) return left;
}
//右
//如果 cur->val 小于 p->val,同时 cur->val 小于 q->val,那么就应该向右遍历(目标区间在右子树)
if(cur->val<p->val && cur->val<q->val){
TreeNode* right=traversal(cur->right,p,q);
if(right!=NULL) return right;
}
//cur节点在区间(p->val <= cur->val && cur->val <= q->val)或者 (q->val <= cur->val && cur->val <= p->val)中,那么cur就是最近公共祖先了,直接返回cur
return cur;
}
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
//普通二叉树求最近公共祖先需要使用回溯,从底向上来查找(需要遍历整棵树)
//本题二叉搜索树就不用了,因为搜索树有序(相当于自带方向 左子树<右子树),那么只要从上向下遍历就可以了(不需要遍历整棵树)
//那么从上到下遍历的时候,cur节点的数值在[p, q]区间中,则说明该节点cur就是最近公共祖先了。那么我们可以采用前序遍历
//(注)参考文章中有简写代码
return traversal(root,p,q);
}
};
运行结果
参考文章:
思路二:减少遍历节点数
代码实现
C++
在这里插入代码片