算法学习|Day21-二叉树|Leetcode530.二叉搜索树的最小绝对差 ,Leetcode501.二叉搜索树中的众数,Leetcode236. 二叉树的最近公共祖先

本文介绍了如何使用递归方法解决LeetCode中的三个二叉搜索树相关问题:最小绝对差、众数查找以及最近公共祖先。重点在于利用二叉搜索树的性质进行高效遍历和判断。
摘要由CSDN通过智能技术生成

一、Leetcode530.二叉搜索树的最小绝对差

题目描述

给你一个二叉搜索树的根节点 root ,返回 树中任意两不同节点值之间的最小差值

差值是一个正数,其数值等于两值之差的绝对值。

在这里插入图片描述
在这里插入图片描述

题目链接:力扣题目链接

解题思路

  • 使用前序
  • 二叉搜索树性质,相邻节点的差较小

方法:递归法

  • 设置最大值,和前一个节点的值pre
  • 终止条件:空节点就返回None
  • 单层递归:左中右,pre不为空就先比较差值,不断更新最小值,最后pre=root
# 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 getMinimumDifference(self, root: Optional[TreeNode]) -> int:
        self.minnum = float('inf')
        self.pre = None
        return self.getMin(root)

    def getMin(self, root):
        if not root:
            return

        # 左
        self.getMin(root.left)

        # 中
        if self.pre is not None:
            self.minnum = min(self.minnum, abs(root.val - self.pre.val))
        self.pre = root

        # 右
        self.getMin(root.right)

        return self.minnum
      

总结

  • 考虑怎么利用二叉搜索树的性质:相邻节点差值小–>利用root.val-pre.val
  • 二叉搜索树使用左中右,中序遍历!


二、Leetcode501.二叉搜索树中的众数

题目描述

给你一个含重复值的二叉搜索树(BST)的根节点 root ,找出并返回 BST 中的所有 众数(即,出现频率最高的元素)。

如果树中有不止一个众数,可以按 任意顺序 返回

假定 BST 满足如下定义:

结点左子树中所含节点的值 小于等于 当前节点的值
结点右子树中所含节点的值 大于等于 当前节点的值
左子树和右子树都是二叉搜索树

在这里插入图片描述

题目链接:力扣题目链接

解题思路

  • 找众数和找差值有点类似
  • 需要有上一个节点和当前节点的记录,需要有最大次数和当前次数,最后存放结果result

方法:递归法

  • 设置参数,pre, maxcount, count, result
  • 终止条件,遇到空节点返回None
  • 单层递归:左中右,
    通过比较pre和root,先记录当前count
    通过比较count和maxcount,更新maxcount和result
# 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 findMode(self, root: Optional[TreeNode]) -> List[int]:
        self.count = 0  # 当前计数
        self.maxcount = 0  # 最大计数
        self.result = []
        self.pre = None
        return self.traversal(root)

    def traversal(self, root):
        if not root:
            return

        self.traversal(root.left)
        if self.pre is None:
            self.count = 1
        elif self.pre.val == root.val:
            self.count += 1
        else:
            self.count = 1
        self.pre = root

        # 只有当 count 等于 maxcount 或大于 maxcount 时,才需要更新结果
        # 这里不要有多余的self.count=1!!!
        if self.count == self.maxcount:
            # 加入不止一个的众数
            self.result.append(root.val)
        if self.count > self.maxcount:
            # 覆盖
            self.maxcount = self.count
            self.result = [root.val]

        self.traversal(root.right)
        return self.result

总结

  • 对于二叉搜索树的差值和众数,都需要设置pre
  • 使用前序遍历!!!


三、Leetcode236. 二叉树的最近公共祖先

题目描述

给定一个二叉树, 找到该树中两个指定节点的最近公共祖先

百度百科中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”

在这里插入图片描述

题目链接:力扣题目链接

解题思路

  • 二叉搜索树,优先中序,但是找公共节点需要使用左右中的顺序,通过左右节点才能判断根节点

方法:递归法

  • 终止条件:空节点返回None, 遇到p或者q返回root
  • 单层递归:左右中
    左右都为空返回None
    左不为空返回left
    右不为空返回right
# 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
        # p和q都是节点,不是比较.val
        if root == p or root == q:
            return root

        left = self.lowestCommonAncestor(root.left, p, q)
        right = self.lowestCommonAncestor(root.right, p, q)

        if left is not None and right is not None:
            return root
        if left is not None and right is None:
            return left
        elif left is None and right is not None:
            return right
        else:
            return None

总结

  • 二叉搜索树优先考虑中序(最小差值,众数)
  • 需要通过左右节点再判断根节点的就使用后序(公共节点)
  • 终止条件大多数为遇到空节点返回None
  • 将多种情况分类清楚!!!


心得:到Day21了,二叉搜索树有点难,多复习巩固一下…加快做题效率!

  • 18
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值