题目

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

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

例如,给定如下二叉树: root = [3,5,1,6,2,0,8,null,null,7,4]

示例 1:
输入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
输出: 3
解释: 节点 5 和节点 1 的最近公共祖先是节点 3。
示例 2:
输入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4
输出: 5
解释: 节点 5 和节点 4 的最近公共祖先是节点 5。因为根据定义最近公共祖先节点可以为节点本身。

说明:

所有节点的值都是唯一的。
p、q 为不同节点且均存在于给定的二叉树中。

思路

首先,需要会:返回二叉树中根节点到任意节点的路径
调用两次该函数,返回p节点和q节点的路径。这里的根节点到任意节点的路径代码思路:笔者的另一篇博客

其次,遍历两个路径数组。因为都是从根节点开始的,所以顺序遍历到相同的值,则是公共祖先。

再次,最近公共祖先,是距离根节点最远的公共祖先,随着循环变量i的增加,不断更新公共祖先,这样得到的就是最远的公共祖先。

leetcode提交

/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     TreeNode *left;*     TreeNode *right;*     TreeNode(int x) : val(x), left(NULL), right(NULL) {}* };*/
class Solution {public:TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {vector<TreeNode*>path;//遍历时候的临时栈 vector<TreeNode*> node_p_path;//p结点路径 vector<TreeNode*> node_q_path; //q结点路径 int finish=0;pre_order(root,p,path,node_p_path,finish);//找到p节点路径 ,存于node_p_path path.clear();//清空 finish=0; //清空 pre_order(root,q,path,node_q_path,finish);//找到q节点路径,存于node_q_path int path_len=0;//较短路径的长度if(node_p_path.size()<node_q_path.size())path_len=node_p_path.size();elsepath_len=node_q_path.size();TreeNode *result=0;for(int i=0;i<path_len;++i){if(node_p_path[i]==node_q_path[i])//相同节点 result=node_p_path[i];//相同则更新,直到距离根节点最远 }return result;            }//前序遍历,找到某一结点的路径resultvoid pre_order(TreeNode * node,TreeNode *search,vector<TreeNode*> &path, vector<TreeNode*> &result,//返回路径结果 int &finish){if(!node||finish==1)//为空或者找到则返回 return;path.push_back(node);//保存节点数值if(node==search){finish=1;result=path;//找到则节点路径保存 } pre_order(node->left,search,path,result,finish);pre_order(node->right,search,path,result,finish);path.pop_back();//结束遍历node时,node节点弹出path栈 }
};

测试代码

 #include<iostream>#include<vector>using namespace std;struct TreeNode{int val;TreeNode* left;TreeNode* right;TreeNode(int x):val(x),left(NULL),right(NULL){}    };class solution{public:TreeNode* lowestCommonAncestor(TreeNode* root,TreeNode *p,TreeNode *q){vector<TreeNode*>path;//遍历时候的临时栈 vector<TreeNode*> node_p_path;//p结点路径 vector<TreeNode*> node_q_path; //q结点路径 int finish=0;pre_order(root,p,path,node_p_path,finish);//找到p节点路径 ,存于node_p_path path.clear();//清空 finish=0; //清空 pre_order(root,q,path,node_q_path,finish);//找到q节点路径,存于node_q_path int path_len=0;//较短路径的长度if(node_p_path.size()<node_q_path.size())path_len=node_p_path.size();elsepath_len=node_q_path.size();TreeNode *result=0;for(int i=0;i<path_len;++i){if(node_p_path[i]==node_q_path[i])//相同节点 result=node_p_path[i];//相同则更新,直到距离根节点最远 }return result;          }void pre_order(TreeNode * node,TreeNode *search,vector<TreeNode*> &path, vector<TreeNode*> &result,//返回路径结果 int &finish){if(!node||finish==1)//为空或者找到则返回 return;path.push_back(node);//保存节点数值if(node==search){finish=1;result=path;//找到则节点路径保存 } pre_order(node->left,search,path,result,finish);pre_order(node->right,search,path,result,finish);path.pop_back();//结束遍历node时,node节点弹出path栈 }};int main(){//暴力构造树TreeNode a(3);TreeNode b(5);TreeNode c(1);TreeNode d(6);TreeNode e(2);TreeNode f(0);TreeNode g(8);TreeNode h(7);TreeNode i(4);a.left=&b;//连接节点a.right=&c;c.left=&f;c.right=&g;b.left=&d;b.right=&e;e.left=&h;e.right=&i;solution solve;TreeNode *result=solve.lowestCommonAncestor(&a,&d,&i) ;cout<<"the Lowest Common Ancestor: "<<result->val<<endl; result=solve.lowestCommonAncestor(&a,&h,&i) ;cout<<"the Lowest Common Ancestor: "<<result->val<<endl; result=solve.lowestCommonAncestor(&a,&d,&g) ;cout<<"the Lowest Common Ancestor: "<<result->val<<endl;     return 0;}

测试结果


题目来源:力扣(LeetCode)
链接:请点击https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-tree

Leetcode236 最近公共祖先-二叉树两次遍历相关推荐

  1. 二叉搜索树最近公共祖先二叉树最近公共祖先

    什么是二叉搜索树? 对于二叉树的任意一个节点n: (1)其左子树下的每个节点的值都小于节点n的值: (2)其左子树下的每个节点的值都大于节点n的值: 思路与算法 从根节点开始遍历: 如果当前节点的值大 ...

  2. 数据结构与算法:已知二叉树两种遍历序列,求第三种遍历序列

    在笔试题目中经常碰到此类题目,已知先序遍历序列和中序遍历序列,求后序序列或者已知中序序列和后序序列,求先序遍历序列.其中若已知先序序列和后序序列,无法唯一确定一棵树,所以就无法得知中序序列. 1.已知 ...

  3. 常考数据结构与算法:在二叉树中找到两个节点的最近公共祖先

    题目描述 给定一棵二叉树以及这棵树上的两个节点 o1 和 o2,请找到 o1 和 o2 的最近公共祖先节点.   假设节点的值都大于0. 比如9,10的最近公共祖先节点是2. 思路: 从根节点开始遍历 ...

  4. 二叉树——求两个节点的最近公共祖先

    题目 给定一颗二叉树的头结点,和这颗二叉树中2个节点n1和n2,求这两个节点的最近公共祖先: 思路 利用后序遍历实现: 对于当前节点cur,如果节点为null或者等于n1或n2中的一个,则直接返回cu ...

  5. 求二叉树中任意两个节点的最近公共祖先节点

    思路:从根节点开始遍历,如果node1和node2中的任一个和root匹配,那么root就是最低公共祖先. 如果都不匹配,则分别递归左.右子树,如果有一个 节点出现在左子树,并且另一个节点出现在右子树 ...

  6. 十九、二叉树的最近的公共祖先

    十九.二叉树的最近的公共祖先 文章目录 十九.二叉树的最近的公共祖先 题目描述 解题思路 上机代码: 题目描述 设顺序存储的二叉树中有编号为 i 和 j 的两个结点,请设计算法求出它们最近的公共祖先结 ...

  7. 023.二叉树的最近公共祖先

    题目链接: 236. 二叉树的最近公共祖先 大概思路: 题目要求: 给定一个二叉树, 找到该树中两个指定节点q,p的最近公共祖先x.(q.p一定存在且值不同) 最近公共祖先: 两个节点共同的祖先,同时 ...

  8. 二叉树的最近公共祖先 (BSF和普通)

    1.若二叉树是一个搜索二叉树 看这个!https://blog.csdn.net/TheWise_lzy/article/details/99610262 从树的根节点开始和两个节点作比较,如果当前节 ...

  9. 二叉树的最近公共祖先、二叉搜索数的最近公共祖先

    目录 二叉树的最近公共祖先 二叉搜索数的最近公共祖先 二叉树的最近公共祖先Ⅱ 二叉树的最近公共祖先Ⅲ 二叉树的最近公共祖先Ⅳ 二叉树的最近公共祖先 给定一个二叉树, 找到该树中两个指定节点的最近公共祖 ...

最新文章

  1. leangoo怎么导入导出,归档和删除看板?
  2. 二叉树题目----4 前序遍历重构二叉树 AND 求二叉树中所有结点的个数
  3. 实时获取滚动条的高度_适用于星上快速处理的雷达高度计有效波高反演技术
  4. ubuntu 改linux密码忘了怎么办,Ubuntu 14.04忘记root密码的解决方法
  5. Linux中锁的总结
  6. Affinity Publisher for Mac(桌面排版神器)中文版
  7. spring加载bean的流程
  8. Python答题并统计的小程序
  9. 吉林大学超星MOOC学习通高级语言程序设计 C++ 实验00 熟悉开发环境(2021级)
  10. GO GOPROXY代理设置
  11. MySQL 中的定时任务
  12. 360,一场阴谋的制造者
  13. (四)Buffer 缓冲区
  14. 计算机在英语中有哪些运用,计算机在英语教学中的运用
  15. 41首送别诗词,首首经典,值得为孩子们收藏!
  16. 求2的零次方 加 2的一次方 加2的二次方等等的和
  17. 雷电模拟器Android obb,exagear模拟器obb数据包
  18. Git 如何生成SSH key
  19. php获取搜索框的函数,PHP自定义函数获取搜索引擎来源关键字的方法
  20. 有关多项式处理的各种算法总结

热门文章

  1. SQL Server里的INTERSECT
  2. (转)VMware 虚拟机安装Ubuntu 11.10使用share folders共享目录
  3. php7.1 改动,PHP7错误处理机制修改
  4. 用神经网络的分类行为理解力的相互作用
  5. 【Paper】2009_Controllability of Multi-Agent Systems from a Graph-Theoretic Perspective
  6. 【控制】《自动控制原理》胡寿松老师-第3章-线性系统的时域分析法
  7. Ardino基础教程 22_PS2摇杆
  8. DC课程笔记-数字逻辑综合工具-DC Environment Attributes
  9. leetcode2 两数相加
  10. snipaste 使用指南