代码随想录算法训练营第23天 |等二刷复习的时候 直接先看这篇 二叉树总结篇 669. 修剪二叉搜索树 108.将有序数组转换为二叉搜索树 538.把二叉搜索树转换为累加树

代码随想录系列文章目录

二叉树篇-二叉搜索树


669. 修剪二叉搜索树

669. 修剪二叉搜索树
如果不对递归有深刻的理解,这道题目还是有难度的

我们写递归的逻辑,对于结点的处理,是要有返回值的,把根节点返回过去,最后才能用root.left, root.right接住返回值,返回root 传回构建出的树

我们遇到超出范围的node,直接返回None 是不对的,这样的话会把node的子树全部扔掉

其实可以根据二叉搜索树的条件去做
1.此时node.val 如果说 小于 low,那说明,它的左子树肯定小于low边界,处理它的右子树就行了,递归调用函数去对它的右子树修建一下,并返回
2.此时node.val如果说 大于high,那说明,它的右子树肯定大于high边界,处理它的左子树就行了,递归调用函数对它的左子树修建一下,并返回这个左子树

在这里插入图片描述

# 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 trimBST(self, root: Optional[TreeNode], low: int, high: int) -> Optional[TreeNode]:
        if not root: return None
        if root.val < low:
            right = self.trimBST(root.right, low, high)
            return right
        if root.val > high:
            left = self.trimBST(root.left, low, high)
            return left
        
        root.left = self.trimBST(root.left, low, high)
        root.right = self.trimBST(root.right, low, high)
        return root

108.将有序数组转换为二叉搜索树

108.将有序数组转换为二叉搜索树
这道题应该和 654.最大二叉树 106.从中序后序构建二叉树 这两道题放在一起,本质就是寻找分割点,分割点作为当前节点,然后递归左区间和右区间

题目中说要转换为一棵高度平衡二叉搜索树。这和转换为一棵普通二叉搜索树有什么差别呢?

其实这里不用强调平衡二叉搜索树,数组构造二叉树,构成平衡树是自然而然的事情,因为大家默认都是从数组中间位置取值作为节点元素,一般不会随机取,所以想构成不平衡的二叉树是自找麻烦。

分割点就是数组中间位置的节点。

那么为问题来了,如果数组长度为偶数,中间节点有两个,取哪一个?

取哪一个都可以,只不过构成了不同的平衡二叉搜索树。

那么这道题的代码和654.最大二叉树一模一样了感觉

# 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 sortedArrayToBST(self, nums: List[int]) -> Optional[TreeNode]:
        if not nums: return None

        root_val = nums[len(nums) // 2]
        root = TreeNode(root_val)

        leftnums = nums[:len(nums) // 2]
        rightnums = nums[len(nums) // 2  + 1 :]

        root.left = self.sortedArrayToBST(leftnums)
        root.right = self.sortedArrayToBST(rightnums)

        return root

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

题目链接

思路:
一看到累加树,相信很多小伙伴都会疑惑:如何累加?遇到一个节点,然后在遍历其他节点累加?怎么一想这么麻烦呢。

然后再发现这是一棵二叉搜索树,二叉搜索树啊,这是有序的啊。

那么有序的元素如果求累加呢?

其实这就是一棵树,大家可能看起来有点别扭,换一个角度来看,这就是一个有序数组[2, 5, 13],求从后到前的累加数组,也就是[20, 18, 13],是不是感觉这就简单了。

为什么变成数组就是感觉简单了呢?

因为数组大家都知道怎么遍历啊,从后向前,挨个累加就完事了,这换成了二叉搜索树,看起来就别扭了一些是不是。

那么知道如何遍历这个二叉树,也就迎刃而解了,从树中可以看出累加的顺序是右中左,所以我们需要反中序遍历这个二叉树,然后顺序累加就可以了。
本题依然需要一个pre指针记录当前遍历节点cur的前一个节点,这样才方便做累加

二叉搜索树 pre指针的使用技巧,参考501.二叉搜索树中的众数
二叉搜索树中的众数 530.搜索树最小绝对差

# 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 convertBST(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
        pre = TreeNode()
        def rec(root):
            nonlocal pre
            if not root:
                return None
            rec(root.right)  #右

            root.val = root.val + pre.val   #中
            pre = root

            rec(root.left)  #左
        
        rec(root)
        return root

二叉树总结篇

等二刷复习的时候 直接先看这篇
二叉树总结篇

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值