day37-2022.12.03
题目信息来源
作者:Krahets
链接:https://leetcode.cn/leetbook/read/illustration-of-algorithm
来源:力扣(LeetCode)
剑指 Offer 68 - I. 二叉搜索树的最近公共祖先
给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。
百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”
例如,给定如下二叉搜索树: root = [6,2,8,0,4,7,9,null,null,3,5]
输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8
输出: 6
解释: 节点 2 和节点 8 的最近公共祖先是 6。
输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 4
输出: 2
解释: 节点 2 和节点 4 的最近公共祖先是 2, 因为根据定义最近公共祖先节点可以为节点本身。
题解:个人题解
# 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':
def searchSameFather(node):
if not node:return False, False
pleft, qleft = searchSameFather(node.left)
pright, qright = searchSameFather(node.right)
pnode = True if node==p else False
qnode = True if node==q else False
left_result = (pleft or pright or pnode)
right_result = (qleft or qright or qnode)
if self.done==False:
if left_result and right_result:
self.result = node
self.done = True
return left_result, right_result
self.result = None
self.done = False
searchSameFather(root)
return self.result
官方题解
个人解法偷懒了一道题的方法用在了两个题的地方。
递归法:
class Solution:
def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
if p.val>q.val:p, q = q, p
if root.val>q.val:return self.lowestCommonAncestor(root.left, p, q)
if root.val<p.val:return self.lowestCommonAncestor(root.right, p, q)
return root
迭代法:
class Solution:
def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
if p.val>q.val:p, q = q, p
while root:
if root.val>q.val:root = root.left
elif root.val<p.val:root = root.right
else:break
return root
day38-2022.12.04
题目信息来源
作者:Krahets
链接:https://leetcode.cn/leetbook/read/illustration-of-algorithm
来源:力扣(LeetCode)
剑指 Offer 68 - II. 二叉树的最近公共祖先
给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。
百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”
例如,给定如下二叉树: root = [3,5,1,6,2,0,8,null,null,7,4]
输入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
输出: 3
解释: 节点 5 和节点 1 的最近公共祖先是节点 3。
输入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4
输出: 5
解释: 节点 5 和节点 4 的最近公共祖先是节点 5。因为根据定义最近公共祖先节点可以为节点本身。
题解:个人题解
偷懒,直接时上一道题的解法,因为上一题我并没有考虑二叉搜索树的特殊性。
思路是:当前节点是 p
和 q
的公共祖先的条件是当前节点的左右节点或者节点本身,有q
和p
匹配上,即 (pleft or pright or pnode)==True
or (qleft or qright or qnode)==True
。有的话标记当前节点为 result
,同时,由于最开始满足条件的节点的父节点,也会是 p
和 q
的公共祖先,但我们需要的是最近的。所以我们需要一个标记 self.done
。
- 递归参数:下一个节点
node.left
ornode.right
- 返回值:
bool
值,两个,是否等于p
和q
。- 如果
node
为空,返回都是 False,也是终止条件 node
不为空,返回值取决于左右子有节点或者节点本身是否等于p
和q
- 如果
# 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:
def searchSameFather(node):
if not node:return False, False
pleft, qleft = searchSameFather(node.left)
pright, qright = searchSameFather(node.right)
pnode = True if node==p else False
qnode = True if node==q else False
left_result = (pleft or pright or pnode)
right_result = (qleft or qright or qnode)
if self.done==False:
if left_result and right_result:
self.result = node
self.done = True
return left_result, right_result
self.result = None
self.done = False
searchSameFather(root)
return self.result
题解:官方题解
class Solution:
def lowestCommonAncestor(self, root: TreeNode, p: TreeNode, q: TreeNode) -> TreeNode:
if root==p or root==q or not root: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