题目大意:
给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。
百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”
例如,给定如下二叉搜索树: root = [6,2,8,0,4,7,9,null,null,3,5]
示例 1:
输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8 输出: 6 解释:节点 2 和节点 8 的最近公共祖先是 6。
示例 2:
输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 4 输出: 2 解释: 节点 2 和节点 4 的最近公共祖先是 2, 因为根据定义最近公共祖先节点可以为节点本身。
说明:
- 所有节点的值都是唯一的。
- p、q 为不同节点且均存在于给定的二叉搜索树中。
解法1:递归
题目中给出是一个二叉搜索树。二叉搜索树:树中任意节点的左子树中所有元素的值均小于该节点的值,该节点右子树中所有节点的值均大于该节点的值。因此p和q的公共祖先的值应该介于左子树和右子树之间。对于p和q,不妨假设p<q(如果不是的话就交换p和q的值嘛),然后从根节点开始遍历,逐层判断:如果根节点的数值均小于p和q的数值,那么代表p和q 的祖先在根节点的右子树中。如果根节点的数值均大于p和q的数值,那么代表p和q 的祖先在根节点的左子树中。如果根节点是否在pq之间,若是则返回该节点,结束判断。
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def lowestCommonAncestor(self, root, p, q):
"""
:type root: TreeNode
:type p: TreeNode
:type q: TreeNode
:rtype: TreeNode
"""
if root == None:
return None
if (root.val>p.val and root.val<q.val) or (root.val<p.val and root.val>q.val):
return root
if root.val > p.val and root.val >q.val:
return self.lowestCommonAncestor(root.left,p,q)
if root.val < p.val and root.val <q.val:
return self.lowestCommonAncestor(root.right,p,q)
return root
另一种写法(意思是一样的):
class Solution(object):
def lowestCommonAncestor(self, root, p, q):
"""
:type root: TreeNode
:type p: TreeNode
:type q: TreeNode
:rtype: TreeNode
"""
if root.val < p.val and root.val < q.val:
return self.lowestCommonAncestor(root.right, p, q)
elif root.val > p.val and root.val > q.val:
return self.lowestCommonAncestor(root.left, p, q)
else:
return root
解法2:不用递归
class Solution(object):
def lowestCommonAncestor(self, root, p, q):
"""
:type root: TreeNode
:type p: TreeNode
:type q: TreeNode
:rtype: TreeNode
"""
while root:
if root.val > max(p.val, q.val):
root = root.left
elif root.val < min(p.val, q.val):
root = root.right
else:
return root
return root
以下是Java版本:
比如如求2和8的LCA,那么为6,博主简单记为LCA(2,8) = 6
更多例子:
LCA(2,4) = 2
LCA(0,5) = 2
很简单的思路就是看两个值在root的哪边:
两个值都在左边,则LCA在左边
两个值都在右边,则LCA在右边
一个在左一个在右,则说明LCA就是当前的root节点。
//利用二叉树的特点,左子树的值小于根小于右子树,利用p,q的值判断所在位置
1. /**
2. * Definition for a binary tree node.
3. * public class TreeNode {
4. * int val;
5. * TreeNode left;
6. * TreeNode right;
7. * TreeNode(int x) { val = x; }
8. * }
9. */
10. public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
11. if(root==null || p==null || q==null)
12. return null;
13. TreeNode m = root;
14.
15. if(m.val > p.val && m.val < q.val){
16. return m;
17. }else if(m.val>p.val && m.val > q.val){
18. return lowestCommonAncestor(root.left, p, q);
19. }else if(m.val<p.val && m.val < q.val){
20. return lowestCommonAncestor(root.right, p, q);
21. }
22.
23. return root;
24. }