236.二叉树的最近公共祖先
🍇 236.二叉树的最近公共祖先
给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。
百度百科 中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”
思路
基本思想
为了找到两个节点的最近公共祖先,需要选择一个遍历方式,此处选择后序遍历,这是因为后序遍历的遍历顺序为左右根,也就是自底向上遍历,这样遇到的第一个祖先就是最近的公共祖先
最近公共祖先的状态右两种:
- p和q分别位于这个公共祖先两边,此时这个节点就是公共祖先
- p或者q就是另外一个节点的祖先,此时p或者q就是公共祖先
相当于要么位于两侧,要么位于一条路径上,第一种情况在图中就是假设p是6,q是2,此时5
就是最近的公共祖先,第二种情况在图中就是假设p为5,q为6,那么p就是最近的公共祖先
此时后序遍历一旦遇到p或者q亦或者空,就立即返回,向上返回时,一旦某个节点的左或者右有返回值,说明遇到了p或者q亦或者空,当返回值不为空时需要进行判断将其分成两种情况:
- 左右都不为空,由于是后序遍历,此时说明当前节点就是遇到的最近的公共祖先,直接返回当前节点
- 左右有一个为空,此时说明不为空的一边遇到了p或者q,此时直接返回原值,也就是不为空的返回值
总结起来就是一旦遇到了p或者q就提前返回,一层一层向上,到了根节点就会退出遍历,此时记录的值就是最近的公共祖先
拿图中举例,假设p是6,q是4,此时后序遍历先遍历左边,一路向下遇到了p,也就是6,此时就提前结束左边的遍历,向上返回,返回到5时,左侧不为空,右侧向下遍历遇到q时一层一层向上返回原值,直到5这个节点,此时由于左右都不为空,向上返回5,到了根节点结束遍历,返回最终的结果5
执行流程
正常的后序遍历
在遇到空返回的条件上加上遇到p或者q也返回
一旦当前节点的左或者右不为空,此时分为两种情况
- 只有一侧不为空,原值向上返回
- 两侧都不为空,返回当前节点
到了根节点退出遍历,返回最终的结果
代码
根据以上分析,得出以下代码:
|
|
总结
遇到p或者q就会一层一层向上返回原值,直到某个节点的左右两侧都不为空,此时返回当前节点,再向上还是返回原值,最终一层一层向上,到了根节点退出遍历,返回最终的结果,就是最近的公共祖先