最近公共祖先 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 };

非递归:

原文地址:https://www.cnblogs.com/demian/p/11031113.html

时间: 2024-10-16 04:48:08

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

快速排序递归非递归队列堆栈实现

递归实现 #include<iostream> using namespace std; template <class T> void QuickSort(T A[],int left,int right) { if(left<right) { int i=left; int j=right+1; do { do i++;while(A[i]<A[left]); do j--;while(A[j]>A[left]); if(i<j) Swap(A[i],A

二叉树总结—建树和4种遍历方式(递归&amp;&amp;非递归)

今天总结一下二叉树,要考离散了,求不挂!二叉树最重要的就是 建立.4种遍历方式,简单应用,如何判断两颗二叉树是否相似 二叉树分为 :1.完全二叉树  2.满二叉树 结构性质: 1).满二叉树 高度为h ,节点数则为 2^h - 1,且叶子节点全在最下层,且叶子节点数为2^(n-1)个{n代表二叉树层数,也叫深度} 2).n个节点的 完全二叉树 深度为 int(log2n)(以2为底n的对数)+ 1: 3).非空二叉树 叶子节点个数==双分支节点数+1 4).非空二叉树 某节点编号 n  若有左孩

【算法拾遗】二分查找递归非递归实现

转载请注明出处:http://blog.csdn.net/ns_code/article/details/33747953 本篇博文没太多要说的,二分查找很简单,也是常见常考的查找算法,以下是递归非递归的实现. 非递归实现: /* 非递归实现,返回对应的序号 */ int BinarySearch(int *arr,int len,int key) { if(arr==NULL || len<1) return -1; int low = 0; int high = len-1; while(l

最近公共祖先(LCA)问题

描述 对于有根树T的两个节点u和v,最近公共祖先LCA(T,u,v)表示一个节点x满足x是u,v的公共祖先且x的深度尽可能大. 算法 求解LCA问题主要有三种解法,分别是暴力搜索,Tanjar算法,最后一种是转化为RMQ问题,用DFS+ST算法来求解 暴力搜索 如果数据量不大的时候可以采用暴力搜索法.先将节点u的祖先节点全部标记出来,然后顺着节点v沿着父亲节点的方向向上遍历,直到遍历到一个被标记的节点,这个节点即为所求节点.或者分别获取u,v到根节点的路径P1,P2,可以将这两条路径看做两个两个

POJ 1470 Closest Common Ancestors【最近公共祖先LCA】

题目链接:http://poj.org/problem?id=1470 题目大意:给出一棵树,再给出若干组数(a,b),输出节点a和节点b的最近公共祖先(LCA) 就是很裸的LCA,但是我用的是<挑战程序设计竞赛>上的"基于二分搜索的算法求LCA",我看网上用的都是tarjan算法.但是我的代码不知道为什么提交上去 wrong answer,自己想的很多测试数据也都和题解结果一样,不知道错在哪里,所以把代码保存一下,留待以后解决...... 如果读者有什么建议,希望提出来,

最近公共祖先LCA(Tarjan算法)的思考和算法实现——转载自Vendetta Blogs

最近公共祖先LCA(Tarjan算法)的思考和算法实现 LCA 最近公共祖先 Tarjan(离线)算法的基本思路及其算法实现 小广告:METO CODE 安溪一中信息学在线评测系统(OJ) //由于这是第一篇博客..有点瑕疵...比如我把false写成了flase...看的时候注意一下! //还有...这篇字比较多 比较杂....毕竟是第一次嘛 将就将就 后面会重新改!!! 首先是最近公共祖先的概念(什么是最近公共祖先?): 在一棵没有环的树上,每个节点肯定有其父亲节点和祖先节点,而最近公共祖先

二叉查找树(6) - 最近公共祖先LCA

给定二叉查找树中的两个节点,求它们的最近公共祖先(Lowest Common Ancestor - LCA). 在详细介绍之前,可以先参考下这篇文章"二叉树(70) - 最近公共祖先[1]" 函数原型定义如下: Node *getLCA(Node* root, int n1, int n2) 其中n1和n2是指定的两个节点值. 例如, 上述BST中,10和14的LCA是12,而8和14的LCA是8. 下面是来自Wikipedia的关于LCA的定义: 假设存在一颗二叉树T, 其中节点n1

求最近公共祖先(LCA)板子 x

LCA目前比较流行的算法主要有tarjian,倍增和树链剖分 1)tarjian 是一种离线算法,需要提前知道所有询问对 算法如下 1.读入所有询问对(u,v),并建好树(建议邻接表) 2.初始化每个节点各属一个并查集,都指向自己 3.对整棵树进行dfs(深度优先搜索)遍历 每处理到一个新节点(u)时看他的另一半(询问对象v)是否visit过,如果visit过了,则这组询问对的lca即v的并查集的根节点,若没有visit过,则继续向下深搜,该节点记为已visit 每当回溯的时候都将子节点的并查集

作业 树和森林 遍历(递归/非递归先序,递归/非递归后序,递归层次)

1 #include <iostream> 2 #include"queue.h"//之前写的类 3 #include"stack.h" //之前写的类 4 using namespace std; 5 6 template <class T> 7 class Tree; 8 9 //======================================== 10 // 树节点类声明 11 template <class T>