• 【Day-35慢就是快】代码随想录-二叉树-二叉搜索树的最近公共祖先


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

    百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”

    思路


    前面的二叉树思路为:利用回溯从底向上搜索,遇到一个节点的左子树里有p,右子树里有q,那么当前节点就是最近公共祖先。

    在有序树里,如果判断一个节点的左子树里有p,右子树里有q呢?

    因为是有序树,所有 如果 中间节点是 q 和 p 的公共祖先,那么 中节点的数组 一定是在 [p, q]区间的。即 中节点 > p && 中节点 < q 或者 中节点 > q && 中节点 < p。

    那么只要从上到下去遍历,遇到 cur节点是数值在[p, q]区间中则一定可以说明该节点cur就是q 和 p的公共祖先。 那问题来了,一定是最近公共祖先吗

    是的,第一次遇到的cur节点在区间[p, q]之间的,就是最近公共祖先。

    递归法

    1. 确定递归参数及返回值

    参数为当前节点,以及两个P, Q;

    返回值为最近公共祖先节点。

    2. 终止条件

    遇到空即可返回

    3. 单层递归逻辑

    在遍历二叉搜索树的时候就是寻找区间[p->val, q->val](注意这里是左闭又闭)

    那么如果 cur->val 大于 p->val,同时 cur->val 大于q->val,那么就应该向左遍历(说明目标区间在左子树上)。

    需要注意的是此时不知道p和q谁大,所以两个都要判断

    1. if (cur->val > p->val && cur->val > q->val) {
    2. TreeNode* left = traversal(cur->left, p, q);
    3. if (left != NULL) {
    4. return left;
    5. }
    6. }

    整体代码:

    1. class Solution {
    2. public:
    3. TreeNode* traversal(TreeNode* cur, TreeNode* p, TreeNode* q){
    4. if(cur == NULL) return cur;
    5. if(cur->val > p->val && cur->val > q->val){
    6. TreeNode* left = traversal(cur->left,p, q);
    7. if(left != NULL) return left;
    8. }
    9. if(cur->val < p->val && cur->val < q->val){
    10. TreeNode* right = traversal(cur->right,p, q);
    11. if(right != NULL) return right;
    12. }
    13. return cur;
    14. }
    15. TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
    16. return traversal(root, p, q);
    17. }
    18. };

    迭代法

    1. class Solution {
    2. public:
    3. TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
    4. while(root){
    5. if(root->val > p->val && root->val >q->val){
    6. root = root->left;
    7. }else if(root->val < p->val && root->val < q->val)
    8. root = root->right;
    9. else return root;
    10. }
    11. return NULL;
    12. }
    13. };

     

  • 相关阅读:
    Lambda 表达式使用详解,一篇文章手把手教会你
    北京大学计算机考研经验分享汇总
    Java很简单的文件上传(transferTo方式)
    基于Qt实现的轻量级CAD画图软件
    数据增强
    使用Java统计gitlab代码行数
    vector 模拟与用法
    Maven插件的作用
    某网站自动下载音乐mp3和歌词 离线音乐
    C:字符串函数(续)-学习笔记
  • 原文地址:https://blog.csdn.net/boru1588/article/details/132852881