最近公共祖先 LCA 递归非递归
给定一棵二叉树,找到两个节点的最近公共父节点(LCA)。
最近公共祖先是两个节点的公共的祖先节点且具有最大深度。
假设给出的两个节点都在树中存在。
dfs递归写法
查找两个node的最近公共祖先,分三种情况:
- 如果两个node在root的两边,那么最近公共祖先就是root。
- 如果两个node在root的左边,那么把root的左子树作为root,再递归。
- 如果两个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 递归非递归的更多相关文章
- [程序员代码面试指南]二叉树问题-在二叉树中找到两个节点的最近公共祖先、[LeetCode]235. 二叉搜索树的最近公共祖先(BST)(非递归)
题目 题解 法一: 按照递归的思维去想: 递归终止条件 递归 返回值 1 如果p.q都不在root为根节点的子树中,返回null 2 如果p.q其中之一在root为根节点的子树中,返回该节点 3 如果 ...
- Reverse Linked List 递归非递归实现
单链表反转--递归非递归实现 Java接口: ListNode reverseList(ListNode head) 非递归的实现 有2种,参考 头结点插入法 就地反转 递归的实现 1) Divide ...
- Luogu 2245 星际导航(最小生成树,最近公共祖先LCA,并查集)
Luogu 2245 星际导航(最小生成树,最近公共祖先LCA,并查集) Description sideman做好了回到Gliese 星球的硬件准备,但是sideman的导航系统还没有完全设计好.为 ...
- POJ 1470 Closest Common Ancestors(最近公共祖先 LCA)
POJ 1470 Closest Common Ancestors(最近公共祖先 LCA) Description Write a program that takes as input a root ...
- POJ 1330 Nearest Common Ancestors / UVALive 2525 Nearest Common Ancestors (最近公共祖先LCA)
POJ 1330 Nearest Common Ancestors / UVALive 2525 Nearest Common Ancestors (最近公共祖先LCA) Description A ...
- 【数据结构】——搜索二叉树的插入,查找和删除(递归&非递归)
一.搜索二叉树的插入,查找,删除 简单说说搜索二叉树概念: 二叉搜索树又称二叉排序树,它或者是一棵空树,或者是具有以下性质的二叉树 若它的左子树不为空,则左子树上所有节点的值都小于根节点的值 若它的右 ...
- [模板] 最近公共祖先/lca
简介 最近公共祖先 \(lca(a,b)\) 指的是a到根的路径和b到n的路径的深度最大的公共点. 定理. 以 \(r\) 为根的树上的路径 \((a,b) = (r,a) + (r,b) - 2 * ...
- 【lhyaaa】最近公共祖先LCA——倍增!!!
高级的算法——倍增!!! 根据LCA的定义,我们可以知道假如有两个节点x和y,则LCA(x,y)是 x 到根的路 径与 y 到根的路径的交汇点,同时也是 x 和 y 之间所有路径中深度最小的节 点,所 ...
- 【Leetcode】查找二叉树中任意结点的最近公共祖先(LCA问题)
寻找最近公共祖先,示例如下: 1 / \ 2 3 / \ / \ 4 5 6 7 / \ ...
随机推荐
- HttpClient学习研究---第二章:连接管理
第二章.Connection management连接管理2.1. 2.1.Connection persistence连接持久性The process of establishing a conne ...
- Daily consumption
Bill record, standard of living, record every consumption, income, expenditure, manage your own life
- Spark两种内存管理
Spark动态内存管理 Spark 1.6 后改为动态内存管理(如果想启用静态内存管理,方法下面会介绍),启动动态主要体现在 存储内存和执行内存的动态.
- tab吸顶的神奇-- css粘性属性
position: -webkit-sticky; position: sticky; top: 0.86rem; //可以自定义设置大小 亲测,目前谷歌浏览器等都已经支持该属性.
- MySQL中列别名为中文时,Order by 子句中使用别名时不要加引号
暂时还不清楚原因 1.按平均成绩从高到低显示所有学生的所有课程的成绩以及平均成绩 SC表: 这里,当做总成绩处理 select sid, sum(score) as '总成绩', avg(score) ...
- 树形DP入门题目推荐以及解析
关于树形DP几道入门题目 今天恶补树形DP,感觉海星. 其实挺简单的. 介绍几道例题,我会的. 1.洛谷P1352 没有上司的舞会 我的一篇题解 我们可以考虑每一个节点都是有两种情况. 一个是被邀请: ...
- cogs 920. [東方S1] 琪露诺
二次联通门 : cogs 920. [東方S1] 琪露诺 /* cogs 920. [東方S1] 琪露诺 dp 方程为dp[i] = max (dp[i - L], dp[i - L + 1] ... ...
- R 指定安装镜像的方法
方法一 options(repos=structure(c(CRAN="https://mirrors.tuna.tsinghua.edu.cn/CRAN/"))) install ...
- elasticsearch-py 解决 too_long_frame_exception 问题
elasticsearch-py 解决 too_long_frame_exception 问题 老大让我搞一搞数据统计,配环境时遇到个奇葩错误,记录一下,希望能帮助到某些人. 我需要安装 Elasti ...
- leetcode 337. 打家劫舍iii
题目描述: 在上次打劫完一条街道之后和一圈房屋后,小偷又发现了一个新的可行窃的地区.这个地区只有一个入口,我们称之为“根”. 除了“根”之外,每栋房子有且只有一个“父“房子与之相连.一番侦察之后,聪明 ...