530.二叉搜索树的最小绝对差

一开始想错了,想着对于二叉搜索树来说,最小差值肯定在父节点和左右子节点之间产生,实际上,根据搜索树的性质,其中序遍历就是一个递增数组,直接在数组中处理就可以了
在递归过程中,用户在每个节点处只计算了当前节点与左右子节点的差的绝对值,但实际上,在二叉搜索树中,最小差值不一定出现在父子节点之间,也可能出现在祖先和后代之间,但由于二叉搜索树的性质,最小差值一定出现在相邻的中序遍历节点之间。
python
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def __init__(self):
self.maxdiff = 10**5+1
self.res = []
def getMinimumDifference(self, root: Optional[TreeNode]) -> int:
self.traversal(root, self.res)
for i in range(len(self.res)-1):
diff = self.res[i+1] - self.res[i]
self.maxdiff = min(diff, self.maxdiff)
return self.maxdiff
def traversal(self, root, res):
if not root:
return
self.traversal(root.left, res)
self.res.append(root.val)
self.traversal(root.right, res)
501.二叉搜索树中的众数

这个题目可以转化为收集到中序的序列数据,然后对此序列寻找众数。然而如何寻找众数呢?
当
self.res[i] == self.res[i-1]时,说明当前数值与前一个相同,current_count加1。当遇到一个不同的数值时,说明前一个数值的连续序列结束了。此时,调用
update_modes方法来判断这个刚刚结束统计的数值是否是众数update_modes方法根据当前数值的计数 (count) 与当前已知的最大计数 (self.maxcount) 进行比较:
如果 count > self.maxcount:这意味着发现了出现次数更多的数。此时,将 self.maxcount更新为这个更大的 count,并清空之前的众数列表 self.out,然后将这个新的众数 val加入列表。
如果 count == self.maxcount:这意味着发现了一个出现次数和当前众数一样多的数。此时,只需将这个数 val追加到众数列表 self.out中即可。
python
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def __init__(self):
self.res = []
self.maxcount = 0
self.out = []
def findMode(self, root: Optional[TreeNode]) -> List[int]:
self.traversal(root,self.res)
current_val = self.res[0]
current_count = 1
for i in range(1, len(self.res)):
if self.res[i] == self.res[i-1]:
current_count += 1
else:
self.update_modes(current_val, current_count)
current_val = self.res[i]
current_count = 1
self.update_modes(current_val, current_count)
return self.out
def update_modes(self, val, count):
"""更新众数列表"""
if count > self.maxcount:
self.maxcount = count
self.out = [val] # 清空之前的结果,重新开始
elif count == self.maxcount:
self.out.append(val) # 相同频率,追加到结果
def traversal(self, root, res):
if not root:
return
self.traversal(root.left, res)
self.res.append(root.val)
self.traversal(root.right, res)
学习了一下不需要额外空间的写法,感觉总体来说区别不太大。
python
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def __init__(self):
self.max_count = 0
self.cur_count = 0
self.pre_value = None
self.res = []
def findMode(self, root: Optional[TreeNode]) -> List[int]:
self.traversal(root)
return self.res
def traversal(self, root):
if not root:
return
self.traversal(root.left)
if root.val != self.pre_value: #与前一个节点不同的情况
self.cur_count = 1
self.pre_value = root.val
else:
self.cur_count += 1
if self.cur_count > self.max_count:
self.res = [root.val]
self.max_count = self.cur_count
elif self.cur_count == self.max_count:
self.res.append(root.val)
self.traversal(root.right)
236. 二叉树的最近公共祖先

总体思想比较好懂,也即分类讨论。
考虑p和q的位置,如果从当前节点看,p和q分别在左右子树里,那么最近公共祖先就是自己,也即root;如果仅左子树或右子树有,那么在存在的那一侧返回;如果都不存在,则返回None,表示既没找到p和q,也算不出最近公共祖先。
复杂的点在于返回值的异质性,即返回"有没有找到p和q",也返回"有没有算出最近公共祖先",理解是当左右子树返回都是非空节点时,此时返回的就是最近公共祖先,再次之前,返回的都是,这里是否有p或q的判断
python
# 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':
if not root:
return None
left = self.lowestCommonAncestor(root.left, p, q)
right = self.lowestCommonAncestor(root.right, p, q)
if root == p or root == q or left and right:
return root
if right:
return right
if left:
return left
补充一下二叉搜索树的最近公共祖先

二叉搜索树的最近公共祖先由于大小排序,可以轻松知道本节点视角下的p和q的位置
python
# 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':
value = root.val
if p.val < value and q.val < value:
return self.lowestCommonAncestor(root.left, p, q)
elif p.val > value and q.val > value:
return self.lowestCommonAncestor(root.right, p, q)
else:
return root