leetcode 236. 二叉树的最近公共祖先

Posted 大忽悠爱忽悠

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了leetcode 236. 二叉树的最近公共祖先相关的知识,希望对你有一定的参考价值。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

二叉树的最近公共祖先题解集合


DFS

  • 对于二叉树中某两个节点的最近公共祖先,存在两种情况:

1.分别位于两个不同的子树中
在这里插入图片描述
在这里插入图片描述

  • 首先,我们知道递归处理的是规模不同,问题相同的事情,这里情况1中
  • 规模不同是处理的每颗二叉树的大小不同,
  • 问题相同指的是都是找当前二叉树的左右子树的根节点为最近的公共祖先

2.位于同一颗子树中
在这里插入图片描述
在这里插入图片描述

  • 同上可知,这里处理的也是规模不同,问题相同的事情
  • 既然都是规模不同,问题相同,那就可以用递归解决

那么用递归解决的思路是什么呢?

从根节点遍历,递归向左右子树查询节点信息
递归终止条件:如果当前节点为空或等于 p 或 q,则返回当前节点

  • 递归遍历左右子树,如果左右子树查到节点都不为空,则表明 p 和 q 分别在左右子树中,因此,当前节点即为最近公共祖先;
  • 如果左右子树其中一个不为空,则返回非空节点,此时返回的非空节点就是最近工作祖先,如果左右子树其中一个为空,则表示当前子树中不存在p和q节点

这里对上面的思路进行画图解释一波:
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

代码:

 class Solution {
 public:
	 TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) 
	 {
		 //如果当前子树中存在p或q则返回的找到的p或q节点
		 //为空表示当前子树没有p或q节点,返回空
		 if (!root || root == p || root == q) return root;
		 //去当前左子树中搜索,如果存在p或者q,就返回对应p或者q节点
		 //不存在返回空
		 TreeNode* left = lowestCommonAncestor(root->left, p, q);
		 //右子树同理
		 TreeNode* right = lowestCommonAncestor(root->right, p, q);
		 //p和q位于不同子树
		 if (left && right) return root;
		 //p和q位于同一子树
		 return left ? left : right;
	 }
 };

在这里插入图片描述


BFS

一层层遍历,遍历每一层的时候,同时记录每个节点的父亲,待找到对应的两个节点后,再寻找这两个节点最近的公共祖先
在这里插入图片描述

 class Solution {
 public:
	 TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) 
	 {
		 if (root == NULL) return NULL;
		 map<TreeNode*,TreeNode*> ret;//存储对应节点和它的父亲节点
		 queue<TreeNode*>  que;
		 que.push(root);//根节点入队
		 ret[root] = NULL;//根节点没有父亲节点
		 //当两个节点都找到时,退出循环
		 while (ret.find(p)==ret.end()||ret.find(q)==ret.end())
		 {
			 TreeNode* temp=que.front();
			 que.pop();
			 if (temp->left)
			 {
				 //左子节点不为空,把它加入到队列中
				 que.push(temp->left);
				 //左子节点不为空,记录下他的父节点
				 ret[temp->left] = temp;
			 }
			 //右节点同上
			 if (temp->right)
			 {
				 que.push(temp->right);
				 ret[temp->right] = temp;
			 }
		 }
		 //寻找p和q的最近的公共祖先
		 set<TreeNode*> ancestor;
		 //记录下p和他的祖先节点,从p节点开始一直到根节点。
		 while (p)
		 {
			 ancestor.insert(p);
			 p = ret[p];
		 }
		 //查看p和他的祖先节点是否包含q节点,如果不包含再看是否包含q的父节点……
		 while (ancestor.end()==ancestor.find(q))
			 q = ret[q];
		 return q;
	 }
 };

在这里插入图片描述


总结

剑指 Offer 68 - II. 二叉树的最近公共祖先一模一样的原题

以上是关于leetcode 236. 二叉树的最近公共祖先的主要内容,如果未能解决你的问题,请参考以下文章

leetcode 236 二叉树的最近公共祖先

leetcode-236二叉树的最近公共祖先

Leetcode 236.二叉树的最近公共祖先

LeetCode236. 二叉树的最近公共祖先

leetcode 236. 二叉树的最近公共祖先

LeetCode Java刷题笔记—236. 二叉树的最近公共祖先