代码随想录刷题训练营DAY22|二叉树part9

669.修剪二叉搜索树

如果区间是[1,3]的话
将节点0的右孩子 节点2 直接赋给 节点3的左孩子就可以了(就是把节点0从二叉树中移除),如图:
在这里插入图片描述

递归三部曲:

  • 确定返回值。删除后新接过来的结点。
  • 确定终止条件:null返回
  • 单层逻辑:
    如果当前root.val小于low,递归遍历右边。
    root.val>hight,递归遍历左边
    在这里插入图片描述
if(root.val < low){
    TreeNode newnode = trimBST(root.right, low, high);
    return newnode; // 返回给上一层需要剪掉的结点
}

这个递归调用返回的TreeNode newnode代表裁剪后的右子树的根节点。
所以,这里的newnode返回的是裁剪后保留下来,并且作为新的树(或子树)根节点的节点。
这个节点及其子节点都是原树中值在[low, high]范围内的节点,这部分树将被“接上”到更高层的适当位置。在这个特定的场景中,由于原节点的值小于low,newnode实际上是原节点右子树上第一个满足值在[low, high]范围内的节点的根节点。

我们有root.val == 0,这个值小于给定的范围[low, high],其中low = 1。根据二叉搜索树的性质,任何在root左子树上的节点也都会小于low(因为在二叉搜索树中,左子树的节点总是小于根节点的值)。因此,这个root节点以及它的左子树都需要被剪除。
我们需要检查root的右子树,因为这里可能有一些节点的值是位于给定的范围[1, 3]内的。在这个例子中,root的右子节点是2,它的值在给定范围内,所以这个节点需要保留。
在这里是如何操作的:
调用trimBST时,首先检查根节点(值为0)。因为0 < low,我们知道这个节点以及它的左子树都不能被保留。
接下来,我们递归调用trimBST(root.right, low, high),在这里root.right就是值为2的节点。
节点2在给定范围内,所以我们会继续递归地调用它的左右子节点,但因为它本身在范围内,它将被作为一个新的根节点返回给它的父节点,即原来的root节点(值为0)。

class Solution {
    public TreeNode trimBST(TreeNode root, int low, int high) {
        if(root==null){
            return null;
        }
        //值小于low,说明这个root和它的左子树全部要剪掉。
        if(root.val<low){
        	//从右边寻找能够替代root的结点
            TreeNode newnode=trimBST(root.right, low, high);
            return newnode;//返回给上一层裁剪后的新节点
        }
        //值大于high,说明这个root和它的右子树全部要剪掉
        if(root.val>high){
            TreeNode newnode=trimBST(root.left, low, high);
            return newnode;
        }
        root.left=trimBST(root.left, low, high);//更新当前的root结点的左边
        root.right=trimBST(root.right, low, high);//更新当前的root结点的右边
        return root;
    }
}

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

思路:找到中间点,把数组一分为二,分别遍历。

递归三部曲:

  • 确定递归函数返回值及其参数。删除二叉树节点,增加二叉树节点,都是用递归函数的返回值来完成,这样是比较方便的。
  • 确定递归终止条件
    这里定义的是左闭右闭的区间,所以当区间 left > right的时候,就是空节点了。
  • 单层递归的逻辑:
    1.取数组中间元素的位置。
int mid = left + ((right - left) / 2);//防止数组越界

2.以中间位置构造结点
3。遍历去构造左右孩子

class Solution {
    public TreeNode sortedArrayToBST(int[] nums) {
        TreeNode root=travelsal(nums,0,nums.length-1);
        return root;
    }

    public TreeNode travelsal(int[] nums,int left,int right){
        if(left>right){
            return null;
        }
        int mid=(left+(right-left)/2);
        TreeNode root=new TreeNode(nums[mid]);//构造新的结点
        root.left=travelsal(nums, left, mid-1);//构造左边
        root.right=travelsal(nums, mid+1, right);//构造右边
        return root;
    }
}
  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值