递归的本质是将大问题拆成相同的规模更小的子问题来解决,把子解决的结果返回到上一层帮助解决大问题。所以递归最需要关注的是单层处理逻辑,也就是中间节点(目标节点)的处理逻辑
终止条件:遍历到叶子节点
单层处理逻辑:在遇到要删除的节点时,不能立马删除,要判断其左子树或者右子树中是否还有符合条件的子树,于是递归其左子树或者右子树,当成更小的问题来解决。然后这里删除一个节点的操作,是将该节点的父节点指向符合条件的子树根节点,返回了两层递归,就能实现这个效果
class Solution {
public TreeNode trimBST(TreeNode root, int low, int high) {
if(root==null){
return null;
}
if(root.val<low){//递归里面套递归,跳了两层,所以能把中间那一层给删了
TreeNode right=trimBST(root.right,low,high);
return right;//将以其右子树为根节点的子树进行修改完后再返回根节点(子问题)
}
if(root.val>high){
TreeNode left=trimBST(root.left,low,high);
return left;
}
root.left=trimBST(root.left,low,high);//
root.right=trimBST(root.right,low,high);
return root;
}
}
这一题和以前的构造二叉树解法一致,找到数组中心的位置作为根节点,然后根据这个节点将数组分为左右子区间,重复这个操作过程,将每一层找到的根节点返回到上一层递归中作为上一层递归节点的左节点或者右节点
class Solution {
public TreeNode sortedArrayToBST(int[] nums) {
return getbst(nums,0,nums.length);
}
public TreeNode getbst(int[] nums,int left,int right){
if(left>=right){
return null;
}
int mid=(left+right)/2;
TreeNode root=new TreeNode(nums[mid]);
root.left=getbst(nums,left,mid);
root.right=getbst(nums,mid+1,right);
return root;
}
}
这一题稍稍转下弯,将中序遍历变一下,改成右中左,定义一个全局变量来记录累加值改变每一个节点的值
class Solution {
int sum=0;
public TreeNode convertBST(TreeNode root) {
getbst(root);
return root;
}
public void getbst(TreeNode node){
if(node==null){
return;
}
getbst(node.right);
sum+=node.val;
node.val=sum;
getbst(node.left);
}
}