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

dfs递归写法

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

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

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

 /**
* Definition of TreeNode:
* class TreeNode {
* public:
* int val;
* TreeNode *left, *right;
* TreeNode(int val) {
* this->val = val;
* this->left = this->right = NULL;
* }
* }
*/ class Solution {
public:
/*
* @param root: The root of the binary search tree.
* @param A: A TreeNode in a Binary.
* @param B: A TreeNode in a Binary.
* @return: Return the least common ancestor(LCA) of the two nodes.
*/
TreeNode * lowestCommonAncestor(TreeNode * root, TreeNode * A, TreeNode * B) {
// write your code here
//如果当前节点为空,或者与目标节点中的一个相同,则返回该节点
if(root == NULL) return NULL;
if(root==A || root==B) return root; //递归寻找A B在左右子树的位置
TreeNode* left = lowestCommonAncestor(root->left,A,B);
TreeNode* right = lowestCommonAncestor(root->right,A,B); //如果A B分别位于root的两侧,则root是他们的LCA,否则是左子树或者右子树
if(left&&right) return root; return left?left:right; }
};

非递归:

后序遍历非递归

 TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if (root == nullptr)
return root;
stack<TreeNode*> s;
vector<TreeNode*> vec; // p和q的公共祖先
bool tag1 = false; // true:找到p
bool tag2 = false; // true:找到q
s.push(root);
TreeNode* lastRoot = root;
while (!s.empty()) // lastRoot(区分从左/右孩子返回)
{
root = s.top();
if (root == p) {
if(tag1 == false && tag2 == false)
vec.push_back(root);
tag1 = true;
}
else if (root == q) {
if (tag2 == false && tag1 == false)
vec.push_back(root);
tag2 = true;
}
if (!tag1 && !tag2)
vec.push_back(root); // 公共祖先入vector
// 找到p,q并且root在公共祖先数组中
if (tag1 && tag2 && find(vec.begin(), vec.end(), root) != vec.end())
return root;
// root的孩子节点还没访问
if (lastRoot != root->right)
{
if (lastRoot != root->left) {
if (root->left != nullptr) {
s.push(root->left);
continue;
}
}
if (root->right != nullptr) {
s.push(root->right);
continue;
}
}
// 孩子节点访问完,弹栈向上回溯
lastRoot = root;
s.pop();
}
return nullptr;
}

最近公共祖先 LCA 递归非递归的更多相关文章

  1. [程序员代码面试指南]二叉树问题-在二叉树中找到两个节点的最近公共祖先、[LeetCode]235. 二叉搜索树的最近公共祖先(BST)(非递归)

    题目 题解 法一: 按照递归的思维去想: 递归终止条件 递归 返回值 1 如果p.q都不在root为根节点的子树中,返回null 2 如果p.q其中之一在root为根节点的子树中,返回该节点 3 如果 ...

  2. Reverse Linked List 递归非递归实现

    单链表反转--递归非递归实现 Java接口: ListNode reverseList(ListNode head) 非递归的实现 有2种,参考 头结点插入法 就地反转 递归的实现 1) Divide ...

  3. Luogu 2245 星际导航(最小生成树,最近公共祖先LCA,并查集)

    Luogu 2245 星际导航(最小生成树,最近公共祖先LCA,并查集) Description sideman做好了回到Gliese 星球的硬件准备,但是sideman的导航系统还没有完全设计好.为 ...

  4. POJ 1470 Closest Common Ancestors(最近公共祖先 LCA)

    POJ 1470 Closest Common Ancestors(最近公共祖先 LCA) Description Write a program that takes as input a root ...

  5. POJ 1330 Nearest Common Ancestors / UVALive 2525 Nearest Common Ancestors (最近公共祖先LCA)

    POJ 1330 Nearest Common Ancestors / UVALive 2525 Nearest Common Ancestors (最近公共祖先LCA) Description A ...

  6. 【数据结构】——搜索二叉树的插入,查找和删除(递归&非递归)

    一.搜索二叉树的插入,查找,删除 简单说说搜索二叉树概念: 二叉搜索树又称二叉排序树,它或者是一棵空树,或者是具有以下性质的二叉树 若它的左子树不为空,则左子树上所有节点的值都小于根节点的值 若它的右 ...

  7. [模板] 最近公共祖先/lca

    简介 最近公共祖先 \(lca(a,b)\) 指的是a到根的路径和b到n的路径的深度最大的公共点. 定理. 以 \(r\) 为根的树上的路径 \((a,b) = (r,a) + (r,b) - 2 * ...

  8. 【lhyaaa】最近公共祖先LCA——倍增!!!

    高级的算法——倍增!!! 根据LCA的定义,我们可以知道假如有两个节点x和y,则LCA(x,y)是 x 到根的路 径与 y 到根的路径的交汇点,同时也是 x 和 y 之间所有路径中深度最小的节 点,所 ...

  9. 【Leetcode】查找二叉树中任意结点的最近公共祖先(LCA问题)

    寻找最近公共祖先,示例如下: 1 /           \ 2           3 /    \        /    \ 4    5      6    7 /    \          ...

随机推荐

  1. HttpClient学习研究---第二章:连接管理

    第二章.Connection management连接管理2.1. 2.1.Connection persistence连接持久性The process of establishing a conne ...

  2. Daily consumption

    Bill record, standard of living, record every consumption, income, expenditure, manage your own life

  3. Spark两种内存管理

    Spark动态内存管理 Spark 1.6 后改为动态内存管理(如果想启用静态内存管理,方法下面会介绍),启动动态主要体现在 存储内存和执行内存的动态.

  4. tab吸顶的神奇-- css粘性属性

    position: -webkit-sticky; position: sticky; top: 0.86rem; //可以自定义设置大小 亲测,目前谷歌浏览器等都已经支持该属性.

  5. MySQL中列别名为中文时,Order by 子句中使用别名时不要加引号

    暂时还不清楚原因 1.按平均成绩从高到低显示所有学生的所有课程的成绩以及平均成绩 SC表: 这里,当做总成绩处理 select sid, sum(score) as '总成绩', avg(score) ...

  6. 树形DP入门题目推荐以及解析

    关于树形DP几道入门题目 今天恶补树形DP,感觉海星. 其实挺简单的. 介绍几道例题,我会的. 1.洛谷P1352 没有上司的舞会 我的一篇题解 我们可以考虑每一个节点都是有两种情况. 一个是被邀请: ...

  7. cogs 920. [東方S1] 琪露诺

    二次联通门 : cogs 920. [東方S1] 琪露诺 /* cogs 920. [東方S1] 琪露诺 dp 方程为dp[i] = max (dp[i - L], dp[i - L + 1] ... ...

  8. R 指定安装镜像的方法

    方法一 options(repos=structure(c(CRAN="https://mirrors.tuna.tsinghua.edu.cn/CRAN/"))) install ...

  9. elasticsearch-py 解决 too_long_frame_exception 问题

    elasticsearch-py 解决 too_long_frame_exception 问题 老大让我搞一搞数据统计,配环境时遇到个奇葩错误,记录一下,希望能帮助到某些人. 我需要安装 Elasti ...

  10. leetcode 337. 打家劫舍iii

    题目描述: 在上次打劫完一条街道之后和一圈房屋后,小偷又发现了一个新的可行窃的地区.这个地区只有一个入口,我们称之为“根”. 除了“根”之外,每栋房子有且只有一个“父“房子与之相连.一番侦察之后,聪明 ...