代码随想录第二十三天

内容:

  1. 修剪二叉搜索树(669)
  2. 将有序数组转换为二叉搜索树(108)
  3. 把二叉搜索树转换为累加树(538)
  4. 二叉树总结

1. 修剪二叉搜索树

难度:🔥🔥🔥

建议:这道题目比较难,比添加和删除节点难的多,建议先看视频理解

1.1 思路分析

我们使用递归三部曲来解决这道题目

因为我们需要通过返回值来连接树之间的关系,所以函数返回TreeNode类型。

终止条件为root == null 此时我们返回null

接下来是单层递归逻辑:

因为这是一颗二叉搜索树,当当前节点的值小于low时,我们递归向该节点的右子树去搜索,因为该节点的右子树的数值可能在我们的范围中,我们将修剪后得到的节点返回给root的左子树。

当当前节点的值大于high时,我们递归向该节点的左子树去搜索,因为该节点的左子树的数值可能在我们的范围中,我们将修剪后得到的节点返回给root的右子树。

最后我们返回修剪后的二叉树的根节点

1.2 代码实现
class Solution {
    public TreeNode trimBST(TreeNode root, int low, int high) {
        if (root == null) {
            return null;
        }
        if (root.val < low) {
            return trimBST(root.right,low,high);
        }
        if (root.val > high) {
            return trimBST(root.left,low,high);
        }
        root.left  = trimBST(root.left,low,high);
        root.right = trimBST(root.right,low,high);

        return root;

    }
}
1.3 注意事项
  • return trimBST(root.right,low,high)这句我们可不可写成return root.right呢?答案是不可以的,因为我们不知道该节点右子树中是否存在小于low的节点。return trimBST(root.left,low,high)同理
1.4 收获总结

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

难度:🔥🔥

建议:本题简单一些,可以尝试先自己做做

2.1 思路分析

这道题的本质就是寻找分割点,分割点作为当前节点,然后递归左区间和右区间

2.2 代码实现
class Solution {
    public TreeNode sortedArrayToBST(int[] nums) {
        TreeNode root = traversal(nums,0,nums.length - 1);
        return root;
    }
    private 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;
    }

}
2.3 注意事项
2.4 收获总结

从中序与后序遍历序列构造二叉树构造一棵最大的二叉树思路相似,以一个节点作为分割点,然后递归处理左区间,右区间。

以及循环不变量在定义区间的使用十分重要。


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

难度:🔥🔥

建议:本题也不难,在求二叉搜索树的最小绝对差众数那两道题都讲过了双指针法,思路也是一样的

3.1 思路分析

从树中可以看出累加的顺序是右中左,所以我们需要反中序遍历这个二叉树,然后顺序累加就可以了,同样我们使用两个指针来方便累加

3.2 代码实现
class Solution {
    int pre;//用于记录前一个节点的值
    public TreeNode convertBST(TreeNode root) {
        pre = 0;
        traversal(root);
        return root;
    }
    private void traversal(TreeNode root){
        if (root == null) {
            return;
        }
        //使用反中序遍历,从大到小
        traversal(root.right);
        root.val += pre;
        pre = root.val;
        traversal(root.left);
    }
}
3.3 注意事项
3.4 收获总结

4.二叉树总结

来自代码随想录

在二叉树题目选择什么遍历顺序是不少同学头疼的事情,我们做了这么多二叉树的题目了,Carl给大家大体分分类

  • 涉及到二叉树的构造,无论普通二叉树还是二叉搜索树一定前序,都是先构造中节点。
  • 求普通二叉树的属性,一般是后序,一般要通过递归函数的返回值做计算。
  • 求二叉搜索树的属性,一定是中序了,要不白瞎了有序性了。

注意在普通二叉树的属性中,我用的是一般为后序,例如单纯求深度就用前序,二叉树:找所有路径也用了前序,这是为了方便让父节点指向子节点。

所以求普通二叉树的属性还是要具体问题具体分析。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值