跃迁引擎

空気を読んだ雨降らないでよ

iOS Research & Development


二叉树的最近公共祖先

剑指 Offer 68 - II. 二叉树的最近公共祖先

题目

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

百度百科中最近公共祖先的定义为:“对于有根树 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 为不同节点且均存在于给定的二叉树中。

题解

思路主要是看如何理解这个最近公共祖先的定义,所谓最近公共祖先,就是输入的两个节点间最近的一个父节点(注意:输入的节点也可能会是自身的父节点,比如在示例图中,输入的节点是5和4,那么5就是他们两个的父节点)。

那么二叉树中什么情况下可以认为是找到公共父节点了呢?有大概这么几种情况:

  • 当p或q其中一个是根节点的时候,那么直接就可以认为这个节点是最近公共祖先
  • 如果p或q分别存在于左右子树中,那么就认为这个左右子树的父节点为最近公共祖先
  • 如果p或q同时都在左子树,或都在右子树,那么就认为该左/右子树的根节点为最近公共祖先
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if (root == null) {
return null;
}
// 如果p或q的其中一个是根节点,那么就可以直接认为这个根节点是最近公共祖先
if (root == p || root == q) {
return root;
}
// 递归遍历左右子树,如果p和q包含在其中,那么返回的节点就不为空
TreeNode left = lowestCommonAncestor(root.left, p, q);
TreeNode right = lowestCommonAncestor(root.right, p, q);
// 如果p和q一个再左树,一个再右树,那么就可以认为root是最近公共祖先
if (left != null && right != null) {
return root;
}
// 如果p和q都在左树,那么左树的根节点就是最近公共祖先
if (left != null) {
return left;
}
// 如果p和q都在右树,那么右树的根节点就是最近公共祖先
if (right != null) {
return right;
}
return null;
}
}
最近的文章

从上到下打印二叉树

剑指 Offer 32 - II. 从上到下打印二叉树 II …

, , 开始阅读
更早的文章

镜像的二叉树

剑指 Offer 27. 二叉树的镜像 …

, , 开始阅读
comments powered by Disqus