Day21|530.二叉搜索树的最小绝对差, 501.二叉搜索树中的众数, 236. 二叉树的最近公共祖先
530.二叉搜索树的最小绝对差
思路
与验证二叉搜索树思路一样,只不过在中序遍历时,得到前后两个节点的差值,并持续记录最小差值。
尝试写代码:
class Solution:
def __init__(self):
self.pre = None
self.minDiff = float('inf')
def getMinimumDifference(self, root: Optional[TreeNode]) -> int:
if not root:
return
self.getMinimumDifference(root.left)
if self.pre:
if self.minDiff > root.val - self.pre.val:
self.minDiff = root.val - self.pre.val
self.pre = root
self.getMinimumDifference(root.right)
return self.minDiff
成功通过!
501.二叉搜索树中的众数
思路
流程与上一题一样,定义一个变量count记录出现的次数,变量val记录出现最多次数的值。
尝试写代码:
class Solution:
def findMode(self, root: Optional[TreeNode]) -> List[int]:
if not root:
return None
self.val = [root.val]
self.maxCount = 0
self.count = 1
self.pre = None
self.traversal(root)
return self.val
def traversal(self, root):
if not root:
return
self.traversal(root.left)
if self.pre:
if root.val == self.pre.val:
self.count += 1
if self.maxCount < self.count:
self.maxCount = self.count
self.val = root.val
else:
self.count = 1
self.traversal(root.right)
结果不对
题目要求返回列表,列表中包含所有众数,上面代码只返回一个众数
对于再一次遍历中能找出众数,而且还有可能数多个,不清楚代码怎么写才是完善的。
根据代码随想录视频
要点:
- 众数可以有多个
- 定义maxCount,存放最多的次数;定义count,计算遍历过程中出现的次数。如果count和maxCount相等,将该节点的值放入result。但是如何确定maxCount中的值就是最大,设计代码技巧。
- 先处理pre和cur两个指针,如果相等,count++,如果不想等,则count=1
- 然后更新maxcount的值,如果count与maxcount相等,把当前节点加入结果集中;如果count大于maxcount,更新maxcount,清理结果集中的值,把当前节点加入。
最终代码:
class Solution:
def findMode(self, root: Optional[TreeNode]) -> List[int]:
self.result = []
self.maxCount = 0
self.count = 0
self.pre = None
self.traversal(root)
return self.result
def traversal(self, root):
if not root:
return
self.traversal(root.left)
if not self.pre:
self.count = 1
elif self.pre.val == root.val:
self.count += 1
else:
self.count = 1
self.pre = root
if self.count == self.maxCount:
self.result.append(root.val)
if self.count > self.maxCount:
self.result.clear()
self.maxCount = self.count
self.result.append(root.val)
self.traversal(root.right)
Python方法
清空列表:
lists.clear()
list = []
236. 二叉树的最近公共祖先
思路
遍历到p节点,记录该节点,接着遍历,分三种情况:
q节点在p节点的子树中
q节点不在p节点的子树中
…
没有思路
根据代码随想录:
要点:
- 从下往上遍历,判断某一个节点左子树出现p;右子树出现q;向上返回该节点
- 因此使用后序遍历,左右中,通过回溯实现上述逻辑
- 终止条件,遇到p或q就向上返回
- 中的处理逻辑:如果左节点和右节点都不为空,则该节点为最近公共祖先
- 第二种情况:p或q本来就是公共祖先。这种情况的处理可以放入第一种情况中。
流程:
- 函数的返回值为公共祖先,参数为p和q
- 终止条件:1)空节点则返回空;2)如果节点等于p或者q,返回该节点
- 中的处理逻辑:如果左右子树都不为空,则当前节点为最近公共祖先;如果一个子树为空,另一个有返回值,则继续向上返回;如果左右都为空,返回None
- 该处理过程包含第二种情况。因为一旦遇到p或q,直接返回该节点,节点下面的值都没有遍历,最终就返回了该节点。
最终代码:
class Solution:
def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
if not root:
return root
if root == p or root == q:
return root
left = self.lowestCommonAncestor(root.left, p, q)
right = self.lowestCommonAncestor(root.right, p, q)
if left and right:
return root
elif left and not right:
return left
elif not left and right:
return right
else:
return None