代码随想录算法训练营 Day21|530.二叉搜索树的最小绝对差, 501.二叉搜索树中的众数, 236. 二叉树的最近公共祖先

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)

结果不对
题目要求返回列表,列表中包含所有众数,上面代码只返回一个众数
对于再一次遍历中能找出众数,而且还有可能数多个,不清楚代码怎么写才是完善的。

根据代码随想录视频
要点:

  1. 众数可以有多个
  2. 定义maxCount,存放最多的次数;定义count,计算遍历过程中出现的次数。如果count和maxCount相等,将该节点的值放入result。但是如何确定maxCount中的值就是最大,设计代码技巧。
  3. 先处理pre和cur两个指针,如果相等,count++,如果不想等,则count=1
  4. 然后更新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节点的子树中

没有思路

根据代码随想录:
要点:

  1. 从下往上遍历,判断某一个节点左子树出现p;右子树出现q;向上返回该节点
  2. 因此使用后序遍历,左右中,通过回溯实现上述逻辑
  3. 终止条件,遇到p或q就向上返回
  4. 中的处理逻辑:如果左节点和右节点都不为空,则该节点为最近公共祖先
  5. 第二种情况:p或q本来就是公共祖先。这种情况的处理可以放入第一种情况中。

流程:

  1. 函数的返回值为公共祖先,参数为p和q
  2. 终止条件:1)空节点则返回空;2)如果节点等于p或者q,返回该节点
  3. 中的处理逻辑:如果左右子树都不为空,则当前节点为最近公共祖先;如果一个子树为空,另一个有返回值,则继续向上返回;如果左右都为空,返回None
  4. 该处理过程包含第二种情况。因为一旦遇到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
  • 6
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值