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

Posted 刘Java

tags:

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

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刷题笔记-数据结构-day18

LeetCode刷题笔记-数据结构-day18

Leetcode刷题Python236. 二叉树的最近公共祖先

[JavaScript 刷题] 树 - leetcode 235 & 236

[JavaScript 刷题] 树 - leetcode 235 & 236

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