• 最近公共祖先 LCA 递归非递归


    给定一棵二叉树,找到两个节点的最近公共父节点(LCA)。
    最近公共祖先是两个节点的公共的祖先节点且具有最大深度。
    假设给出的两个节点都在树中存在。

    dfs递归写法

    查找两个node的最近公共祖先,分三种情况:

    1. 如果两个node在root的两边,那么最近公共祖先就是root。
    2. 如果两个node在root的左边,那么把root的左子树作为root,再递归。
    3. 如果两个node在root的右边,那么把root的右子树作为root,再递归。

    深度优先遍历二叉树,一旦找到了两个节点其中的一个,就将这个几点返回给上一层,上一层节点通过判断其左右子树中是否恰好包含n1和n2两个节点,如果找到,对应的上一层节点肯定是所求的LCA;若果不是,将包括两个节点中任意一个的较低的节点返回给上一层,否则返回NULL。

     1 /**
     2  * Definition of TreeNode:
     3  * class TreeNode {
     4  * public:
     5  *     int val;
     6  *     TreeNode *left, *right;
     7  *     TreeNode(int val) {
     8  *         this->val = val;
     9  *         this->left = this->right = NULL;
    10  *     }
    11  * }
    12  */
    13 
    14 
    15 class Solution {
    16 public:
    17     /*
    18      * @param root: The root of the binary search tree.
    19      * @param A: A TreeNode in a Binary.
    20      * @param B: A TreeNode in a Binary.
    21      * @return: Return the least common ancestor(LCA) of the two nodes.
    22      */
    23     TreeNode * lowestCommonAncestor(TreeNode * root, TreeNode * A, TreeNode * B) {
    24         // write your code here
    25         //如果当前节点为空,或者与目标节点中的一个相同,则返回该节点
    26         if(root == NULL)    return NULL;
    27         if(root==A || root==B)  return root;
    28         
    29         //递归寻找A B在左右子树的位置
    30         TreeNode* left = lowestCommonAncestor(root->left,A,B);
    31         TreeNode* right = lowestCommonAncestor(root->right,A,B);
    32         
    33         //如果A B分别位于root的两侧,则root是他们的LCA,否则是左子树或者右子树
    34         if(left&&right) return root;
    35         
    36         return left?left:right;
    37         
    38         
    39     }
    40 };

    非递归:

    后序遍历非递归

     1 TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
     2     if (root == nullptr)
     3         return root;
     4     stack<TreeNode*> s;
     5     vector<TreeNode*> vec; // p和q的公共祖先
     6     bool tag1 = false; // true:找到p
     7     bool tag2 = false; // true:找到q
     8     s.push(root);
     9     TreeNode* lastRoot = root;
    10     while (!s.empty()) // lastRoot(区分从左/右孩子返回)
    11     {
    12         root = s.top();
    13         if (root == p) {
    14             if(tag1 == false && tag2 == false)
    15                 vec.push_back(root);
    16             tag1 = true;
    17         }
    18         else if (root == q) {
    19             if (tag2 == false && tag1 == false)
    20                 vec.push_back(root);
    21             tag2 = true;
    22         }
    23         if (!tag1 && !tag2)
    24             vec.push_back(root); // 公共祖先入vector
    25         // 找到p,q并且root在公共祖先数组中
    26         if (tag1 && tag2 && find(vec.begin(), vec.end(), root) != vec.end())
    27             return root;
    28         // root的孩子节点还没访问
    29         if (lastRoot != root->right)
    30         {
    31             if (lastRoot != root->left) {
    32                 if (root->left != nullptr) {
    33                     s.push(root->left);
    34                     continue;
    35                 }
    36             }
    37             if (root->right != nullptr) {
    38                 s.push(root->right);
    39                 continue;
    40             }
    41         }
    42         // 孩子节点访问完,弹栈向上回溯
    43         lastRoot = root;
    44         s.pop();
    45     }
    46     return nullptr;
    47 }
  • 相关阅读:
    C#关于日期 月 天数 和一年有多少周及根据某年某周获取时间段的计算
    配置tomcat
    C# 动态编译及反射执行
    数据库日志自增量太大导致超时
    validateRequest验证引发错误“检测到有潜在危险的 Request.Form 值”
    入手了DELL Ultrabook,还不错哦!
    Spring.NET学习笔记1——控制反转(基础篇)
    Win7 64位下Kindle4、闪迪Cruzer BladeU盘等无法安装驱动问题的解决方法
    转:CentOS 5.5下LVM分区在线扩容
    [转]关于64位Sublime Text 2破解注册码的方法
  • 原文地址:https://www.cnblogs.com/demian/p/11031113.html
Copyright © 2020-2023  润新知