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

本文介绍了如何通过代码实现二叉搜索树的修剪(669.修剪二叉搜索树),以及将有序数组转换为平衡二叉搜索树(108.有序数组转BST)。还涉及了把二叉搜索树转换为累加树(538. BST to Cumulative Sum Tree)的过程。
摘要由CSDN通过智能技术生成

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

669. 修剪二叉搜索树

  1. 去模拟 举例 想一遍 如果该节点小于low 应该要去遍历他的右子树 去除比Low小的 return right
  2. 如果没找到的话 就返回的是null
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public TreeNode trimBST(TreeNode root, int low, int high) {
        //终止条件
        if(root==null) return null;
        //如果该节点值小于Low 那就去递归该节点的右子树 因为右子树中有可能存在比Low大的值 然后返回右子树的头节点
        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;
    }
}

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

  1. 构造二叉树 一般是把树分为左区间和右区间
  2. 由于题目要求说 要平衡的 说明高度差不能超过1
  3. 所以从中最中间的节点作为 根节点 这样左子树 就在左边 右子树 就在右边 个数也相等
  4. 递归下去 左子树 的根节点 也在数组左半区间的 中间 区间可以定义成左闭右闭
  5. 至于若数组元素个数 为偶数个 中间节点位置靠左和靠右是 一样的 两种结构 都行
  6. 终止条件 由于定义的区间为左闭右闭 那么当左边界 > 右边界时 结束
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public TreeNode sortedArrayToBST(int[] nums) {
        return traversal(nums,0,nums.length-1);

    }

    public TreeNode traversal(int[] nums,int left,int right){
        //终止条件
        //区间定义为左闭右闭 
        if(left>right) return null;
        //找根节点
        int mid = (left+right)/2;
        TreeNode root = new TreeNode(nums[mid]);

        //向左右递归
        root.left = traversal(nums,left,mid-1);
        root.right = traversal(nums,mid+1,right);
        return root;
    }
}

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

  1. 因为中序遍历 获得的是从小到大的升序数组 所以反过来 右中左遍历累加 符合题意 用全局变量sum
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    int sum = 0;

    public TreeNode convertBST(TreeNode root) {
        traversal(root);
        return root;

    }

    public void traversal(TreeNode root){
        //终止条件
        if(root==null) return;

        //右中左遍历  值是从小到大的  每个节点的值就是前面节点加上本节点值 
        traversal(root.right);
        //中 这一层遍历的操作
        //累加每一次的节点值
        sum+=root.val;
        //把sum赋值给当前root
        root.val = sum;
        //向左遍历
        traversal(root.left);
        return;

    }
}

双指针

  1. 定义全局变量pre 指向前一个节点 右中左遍历累加
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    //int sum = 0;
    TreeNode pre =null;
    public TreeNode convertBST(TreeNode root) {
        traversal(root);
        return root;

    }

    public void traversal(TreeNode root){
        //终止条件
        if(root==null) return;

        //右中左遍历  值是从小到大的  每个节点的值就是前面节点加上本节点值 
        traversal(root.right);
        //中
        if(pre!=null){
            root.val+=pre.val;

        }
        pre = root;
        traversal(root.left);
        return;

    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值