代码随想录算法训练营第二十三天|669. 修剪二叉搜索树 、108.将有序数组转换为二叉搜索树 、538.把二叉搜索树转换为累加树

目录

Leetcode - 699

Leetcode - 108

Leetcode - 538


Leetcode - 699

这题虽然代码不复杂,但是挺难想的,最核心的一点就是要考虑到待删除节点的字数,若一个节点的值小于左边界,但是这个节点可能存在右子树,且由于右子树里的节点都大于该节点,所以是可能存在区间内部的点,此时要继续向右递归。同理,节点的值大于右边界,就要考虑左子树,再进行一次递归。此时递归后的结果应该返回给上上层 (因为这里是两次递归),也就是节点的父节点。

小于左边界的节点,肯定是存在于左子树中的,这里可能会有疑问,这种节点可能也存在于右子树中? 是的,因为这里我们把判断逻辑写在前面,左右递归写在后面,所以是先序遍历,先序遍历中肯定是一直往左找,直到找到符合删除条件的节点,此时我们再往右进行第二次遍历,返回的结果就是一颗干净的右子树了,直接作为父节点的左孩子

def trimBST(self, root: Optional[TreeNode], low: int, high: int) -> Optional[TreeNode]:
        def delete(root,low,high):
            if root == None:
                return root
            
            if root.val < low:
                right = delete(root.right,low,high)
                return right

            if root.val > high:
                left = delete(root.left,low,high)
                return left

            root.left = delete(root.left,low,high)
            root.right = delete(root.right,low,high)

            return root

        

        return delete(root,low,high)

这里也可以这样解释,在找到符合小于左边界的节点前,我们是跳过了前面的判断逻辑,一直在执行delete(root.left,low,high),所以肯定是现在左子树中找到目标节点,然后将一颗干净的数返回给父节点的左边。  右子树同理

Leetcode - 108

这题就是一个不断二分的过程,每次对数组平均划分为两部分,高度差不会超过1,先取中间节点为跟节点,通过根节点在数组中的Index,划分左右子树,终止条件就是对子树区间的判断,若为空(如长度为1的数组,1//2 =0,那么左子树就为空),返回None, 若只有一个元素,那么就返回以这个元素为值的node。右子树在划分时的形式是[index+1:]但是有可能index+1会越界,这里需要加一个判断,若越界。则说明右子树为空,直接root.right = None,若不为空,则将右区间传入递归并返回给右节点,因为左子树不会出现越界异常,可直接通过终止条件来判断,不需要额外加判断。

def sortedArrayToBST(self, nums: List[int]) -> Optional[TreeNode]:
        def create(nums):
            if len(nums)==1:
                return TreeNode(val = nums[0])
            if nums == []:
                return None

            index = len(nums)//2
            root = TreeNode(val = nums[index])
            if index +1 < len(nums):
                right = nums[index+1:]
                root.right = create(right)
            else:
                root.right = None
            
            left = nums[:index]
            root.left = create(left)
            
            return root

        return create(nums)

Leetcode - 538

我们知道如果中序遍历,对于排序二叉树来说就是一个由小到大的有序序列。本题要求当前节点的值要加上所有比自己大的节点的值,那么对于序列来说,就是加上排在自己后面的数的值,那其实可以这样看,倒数第一个元素因为后面没数,所以不加,倒数第二个元素加上倒数第一个的值,倒数第三个加上倒数第二和倒数第一的值,其实这里就等于直接加上更新后的倒数第二个元素的值,其实就是一个逆向的累加的过程。所以 我们可以做一个中序的逆向遍历,然后用Pre指针指向上一个节点,然后每次root的值就加上Pre的值即可。

def convertBST(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
        pre = TreeNode()
        def accumulate(root):
            nonlocal pre
            if not root:
                return None
            
            accumulate(root.right)
            root.val += pre.val
            pre = root
            accumulate(root.left)
        
        accumulate(root)
        return root

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值