235/236-二叉树最近公共祖先

235/236-二叉树最近公共祖先

力扣235

https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-search-tree/

235题目

二叉搜索树的性质:左子树<根<右子树。因此当前节点要做的事情很简单:

我们只需要判断当前节点和要找的两个节点p, q比较大小

root.val比p.val和q.val都小,公共节点肯定不是他,在右子树

root.val比p.val和q.val都大,公共节点肯定不是他,在左子树

root.val在p.val和q.val之间,公共节点肯定是他

对于特殊情况:公共祖先就是p或者q的情况,因为我们递归从上往下遍历,先到达的那个是p就返回p,是q就返回q,所以这个特殊情况的判断放在前序遍历的位置

1
2
3
4
5
6
7
8
9
10
11
12
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if(root == null) return root;

if (p == root || q == root) return root; //越靠近根的那个是在前序遍历位置

if (p.val < root.val && q.val < root.val) {
return lowestCommonAncestor(root.left, p, q);
}else if (p.val > root.val && q.val > root.val) {
return lowestCommonAncestor(root.right, p, q);
}
return root;
}

妙就妙在判断的顺序,先判断全左和全右,这样就不需要判断p和q哪个大,夹在中间时p < root < q还是q < root < p


力扣236

https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-tree/

236题目

思考过程:没有了二叉排序树的性质,那只能左右遍历了,当前节点要做的事:如果左右子树包含p,q就说明当前节点是最近公共祖先。那p,q肯定不会说一直都在同一层,所以是由下层返回的才能判断,后序遍历位置理所当然

思路:后序遍历位置,左右递归后返回的结果记录下来,返回的结果应该是:如果是要找的p或q,那么一直沿父节点返回,否则直接返回null。那么递归回来的时候,公共祖先左右两边节点就是p和q,否则的话左右两边为null

看图比较直观:

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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
后序遍历,所以从叶子节点开始,假设树如下,要找的节点是8和4
3
/ \
/ \
/ \
/ \
5 1
/ \ / \
/ \ / \
6 2 0 8
/ \
7 4

3
/ \
/ \
/ \
/ \
5 1
/ \ / \
/ \ / \
6 2 0 8
/ \
null 4

3
/ \
/ \
/ \
/ \
5 1
/ \ / \
/ \ / \
null 4 null 8
/ \
null 4

3
/ \
/ \
/ \
/ \
4 8
/ \ / \
/ \ / \
null 4 null 8
/ \
null 4

3 返回到当前节点为3时,左右都不为null(不需要判断具体左和右),成了
/ \
/ \
/ \
/ \
4 8
/ \ / \
/ \ / \
null 4 null 8
/ \
null 4

代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if(root == null) return root;

if (p == root || q == root) return root; //找到了

TreeNode left = lowestCommonAncestor(root.left,p,q);
TreeNode right = lowestCommonAncestor(root.right,p,q);

if(left!=null && right != null) return root; //只需要判断是否为null
else if (left != null) return left;
else if (right != null) return right;
return null;
}

妙就妙在只需要判断是否为null即可而不需要判断是否是p还是q,不为null那么一定是p或者q,左右都不为null一定是公共祖先

特殊情况:p,q恰好是公共祖先的特判刚好也能判到

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×