leetcode分类刷题:二叉树(七、中序遍历解决二叉搜索树)

1、二叉搜索树是一个有序树:每个二叉树都满足左子树上所有节点的值均小于它的根节点的值,右子树上所有节点的值均大于它的根节点的值;因此,它的中序遍历是一个升序序列,有没有重复元素根据具体题意而定
2、本次总结的题型,采用迭代循环的中序遍历+标记节点的思路解决,简单直观

98. 验证二叉搜索树

二叉搜索树的性质,中序遍历完是一个递增序列!利用中序遍历的迭代循环形式,添加一个pre指针标记递增序列的上一个元素

'''
98. 验证二叉搜索树
给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。
有效 二叉搜索树定义如下:
节点的左子树只包含 小于 当前节点的数。
节点的右子树只包含 大于 当前节点的数。
所有左子树和右子树自身必须也是二叉搜索树。
示例 2:
    输入:root = [5,1,4,null,null,3,6]
    输出:false
    解释:根节点的值是 5 ,但是右子节点的值是 4 。
思路:二叉搜索树的性质,中序遍历完是一个递增序列!利用中序遍历的迭代循环形式,添加一个pre指针标记递增序列的上一个元素
'''
class Solution:
    # 用中序遍历的迭代循环形式,添加一个pre指针标记递增序列的上一个元素
    def isValidBST(self, root: Optional[TreeNode]) -> bool:
        if not root:
            return True
        stack = []
        pre = None
        cur = root
        while cur != None or len(stack) > 0:
            # 先访问到最底层最左侧的节点
            if cur != None:
                stack.append(cur)
                cur = cur.left         # 左
            # 到达最左结点后处理栈顶结点
            else:
                cur = stack.pop()      # 中:这个节点一定不为空
                if pre != None and pre.val >= cur.val:
                    return False
                pre = cur
                cur = cur.right        # 右
        return True

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

思路:二叉搜索树的性质,中序遍历完是一个递增序列!那么序列中两两元素之间的差值肯定是最小的。利用中序遍历的迭代循环形式,添加一个pre指针标记递增序列的上一个元素,不断更新最小绝对差

'''
530. 二叉搜索树的最小绝对差
给你一个二叉搜索树的根节点 root ,返回 树中任意两不同节点值之间的最小差值 。
差值是一个正数,其数值等于两值之差的绝对值。
示例 1:
    输入:root = [1,0,48,null,null,12,49]
    输出:1
思路:二叉搜索树的性质,中序遍历完是一个递增序列!那么序列中两两元素之间的差值肯定是最小的。
利用中序遍历的迭代循环形式,添加一个pre指针标记递增序列的上一个元素,不断更新最小绝对差
'''
class Solution:
    def getMinimumDifference(self, root: Optional[TreeNode]) -> int:
        stack = []
        pre = None
        cur = root
        result = float('inf')
        while cur != None or len(stack) > 0:
            # 先访问到最底层最左侧的节点
            if cur != None:
                stack.append(cur)
                cur = cur.left         # 左
            # 到达最左结点后处理栈顶结点
            else:
                cur = stack.pop()      # 中:这个节点一定不为空
                if pre != None:
                    result = min(result, cur.val - pre.val)
                pre = cur
                cur = cur.right        # 右
        return result

501. 二叉搜索树中的众数

思路:二叉搜索树的性质,中序遍历完是一个递增序列!相当于对递增数组求众数。利用中序遍历的迭代循环形式,添加一个pre指针标记递增序列的上一个元素,同时为了一次遍历找到所有众数,需要额外再添加两个频率标志

'''
501. 二叉搜索树中的众数
给你一个含重复值的二叉搜索树(BST)的根节点 root ,找出并返回 BST 中的所有 众数(即,出现频率最高的元素)。
如果树中有不止一个众数,可以按 任意顺序 返回。
假定 BST 满足如下定义:
结点左子树中所含节点的值 小于等于 当前节点的值
结点右子树中所含节点的值 大于等于 当前节点的值
左子树和右子树都是二叉搜索树
示例 1:
    输入:root = [1,null,2,2]
    输出:[2]
思路:二叉搜索树的性质,中序遍历完是一个递增序列!相当于对递增数组求众数。
利用中序遍历的迭代循环形式,添加一个pre指针标记递增序列的上一个元素,同时为了一次遍历找到所有众数,需要额外再添加两个频率标志
'''
class Solution:
    def findMode(self, root: Optional[TreeNode]) -> List[int]:
        if not root:
            return []
        # 中序遍历BST得到递增序列
        stack = []
        cur = root
        result = []
        # 定义三个标志
        pre = None  # 第一次有效的标志
        count, maxCount = 0, 0  # 统计频率,最大频率
        while cur != None or len(stack) > 0:
            # 一直遍历到最底层最左侧的节点
            if cur != None:
                stack.append(cur)
                cur = cur.left                # 左
            else:
                cur = stack.pop()             # 根
                # 1、统计单个数值的频率
                if pre == None:
                    count = 1
                elif cur.val != pre.val:
                    count = 1
                elif cur.val == pre.val:
                    count += 1
                # 2、维护result数组
                if count == maxCount:
                    result.append(cur.val)
                elif count > maxCount:
                    maxCount = count
                    result.clear()  # python原来有清除函数
                    result.append(cur.val)
                pre = cur
                cur = cur.right               # 右
        return result

538. 把二叉搜索树转换为累加树

二叉搜索树的性质,中序遍历完是一个递增序列!很明显是用中序遍历逆序+标记的思路解决
本题与“1038. 从二叉搜索树到更大和树”相同

'''
538. 把二叉搜索树转换为累加树
1038. 从二叉搜索树到更大和树
给出二叉 搜索 树的根节点,该树的节点值各不相同,请你将其转换为累加树(Greater Sum Tree),使每个节点 node 的新值等于原树中大于或等于 node.val 的值之和。
提醒一下,二叉搜索树满足下列约束条件:
节点的左子树仅包含键 小于 节点键的节点。
节点的右子树仅包含键 大于 节点键的节点。
左右子树也必须是二叉搜索树。
示例 1:
    输入:[4,1,6,0,2,5,7,null,null,null,3,null,null,null,8]
    输出:[30,36,21,36,35,26,15,null,null,null,33,null,null,null,8]
思路:二叉搜索树的性质,中序遍历完是一个递增序列!很明显是用中序遍历逆序+标记的思路解决。
'''
class Solution:
    def convertBST(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
        # 很明显是用中序遍历逆序+标记的思路
        stk = []
        cur = root
        s = 0
        while cur != None or len(stk) > 0:
            if cur != None:
                stk.append(cur)
                cur = cur.right  # 右
            else:
                cur = stk.pop()  # 中
                s += cur.val
                cur.val = s
                cur = cur.left  # 左
        return root
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

22世纪冲刺

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值