LeetCode Java刷题笔记—236. 二叉树的最近公共祖先
Posted 刘Java
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode Java刷题笔记—236. 二叉树的最近公共祖先相关的知识,希望对你有一定的参考价值。
给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”
中等难度。这种题就是经典的LCA问题,采用递归分治+自底向上后序遍历即可用较少的代码写出来。
public TreeNode lowestCommonAncestor( TreeNode root, TreeNode p, TreeNode
q )
//递归返回的条件,要么root为null,这表示可能是递归到了最底层
//要么root等于p或者q,这表示已经找到了等于p或者q的节点,没必要继续向下递归
if( root == null || root == p || root == q )
return root;
/*分 拆解*/
TreeNode left = lowestCommonAncestor( root.left, p, q );
TreeNode right = lowestCommonAncestor( root.right, p, q );
/*治 合并*/
//如果左右子节点都不null,那么表示p和q都是找到了,那么返回root父节点
//如果有一个子节点为null,那么返回另一个节点,这表示最近公共祖先就是另一个节点
//最终将会导致这个函数要么返回null,表示没有最近公共祖先
//要么返回p或者q节点,表示两个节点的最近公共祖先是其中一个节点
//要么返回root,表示两个节点的最近公共祖先是该节点
return left == null ? right : right == null ? left : root;
另一种方法思想更加简单,我们可以用哈希表存储所有节点的父节点,然后我们就可以利用节点的父节点信息从 p 结点开始不断往上跳,并记录已经访问过的节点,再从 q 节点开始不断往上跳,如果碰到已经访问过的节点,那么这个节点就是我们要找的最近公共祖先。
//存储子节点和父节点的关系映射
Map<Integer, TreeNode> parent = new HashMap<Integer, TreeNode>();
Set<Integer> visited = new HashSet<Integer>();
public TreeNode lowestCommonAncestor( TreeNode root, TreeNode p, TreeNode q )
//将整棵树的父子节点关系存储起来
dfs( root );
//循环存储从p节点开始到其父节点的路径
while( p != null )
visited.add( p.val );
p = parent.get( p.val );
//同样从q节点开始循环查找其父节点是否在这条路径中
while( q != null )
//如果路径中包含q,那么返回q,即q就是最近公共祖先
if( visited.contains( q.val ) )
return q;
q = parent.get( q.val );
return null;
/**
* 将整棵树的父子节点关系存储起来
*
* @param root
*/
public void dfs( TreeNode root )
if( root.left != null )
parent.put( root.left.val, root );
dfs( root.left );
if( root.right != null )
parent.put( root.right.val, root );
dfs( root.right );
以上是关于LeetCode Java刷题笔记—236. 二叉树的最近公共祖先的主要内容,如果未能解决你的问题,请参考以下文章
Leetcode刷题Python236. 二叉树的最近公共祖先
[JavaScript 刷题] 树 - leetcode 235 & 236