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;
}
}