题目描述:
I. 给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。
百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”
II. 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。
示例:
输入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
输出: 3
解释: 节点 5 和节点 1 的最近公共祖先是节点 3
思路:
我在做的时候是把根到结点的路径求出来,然后求两个路径最后重合的那个节点;
题解中给出了新的思路:
首先,二叉搜索树是左子树<根<右子树,所以找到一个结点使得p在左边,q在右边,那就是这个结点。
二叉搜索树:
class Solution:
def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
while root:
if root.val < p.val and root.val < q.val: # p,q 都在 root 的右子树中
root = root.right # 遍历至右子节点
elif root.val > p.val and root.val > q.val: # p,q 都在 root 的左子树中
root = root.left # 遍历至左子节点
else: break
return root
二叉树:(会稍微复杂一点,用到递归)
class Solution:
def lowestCommonAncestor(self, root: TreeNode, p: TreeNode, q: TreeNode) -> TreeNode:
if not root or root == p or root == q: return root
left = self.lowestCommonAncestor(root.left, p, q)
right = self.lowestCommonAncestor(root.right, p, q)
if not left: return right
if not right: return left
return root
具体题解思路:
链接
自己的求路径的方法:
二叉搜索树:
# 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: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
lista = self.path(root, p)
listb = self.path(root, q)
# print(lista, listb)
for i in range(len(lista)-1, -1, -1):
for j in range(len(listb)):
if listb[j] == lista[i]:
return listb[j]
def path(self, root, node):
path_root = []
while root != node:
path_root.append(root)
if node.val > root.val:
root = root.right
else:
root = root.left
path_root.append(node)
return path_root
二叉树:
# 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: TreeNode, p: TreeNode, q: TreeNode) -> TreeNode:
lista = self.path(root, p, [])
listb = self.path(root, q, [])
# for k in lista:
# print("a:",k.val)
# for p in listb:
# print("b:",p.val)
for i in range(len(lista)-1, -1, -1):
if lista[i] in listb:
return lista[i]
def path(self, root, node, path_root):
if not root: return
if root == node:
path_root += [root]
return path_root
a = self.path(root.left, node, path_root+[root])
if not a:
return self.path(root.right, node, path_root+[root])
else:
return a
注意求解路径的方式(递归的方式)