day19|669. 修剪二叉搜索树、108.将有序数组转换为二叉搜索树、538.把二叉搜索树转换为累加树

文章介绍了如何对二叉搜索树进行修剪,使其所有节点值位于特定范围内,以及如何将有序数组转换为高度平衡的二叉搜索树。此外,还讨论了如何将二叉搜索树转化为累加树,即每个节点值等于原树中大于或等于其值的节点之和。这些操作都涉及到递归和二叉树性质的应用。
摘要由CSDN通过智能技术生成

669. 修剪二叉搜索树

给你二叉搜索树的根节点 root ,同时给定最小边界low 和最大边界 high。通过修剪二叉搜索树,使得所有节点的值在[low, high]中。修剪树 不应该 改变保留在树中的元素的相对结构 (即,如果没有被移除,原有的父代子代关系都应当保留)。 可以证明,存在 唯一的答案 。

所以结果应当返回修剪好的二叉搜索树的新的根节点。注意,根节点可能会根据给定的边界发生改变。

示例 1:

输入:root = [1,0,2], low = 1, high = 2

输出:[1,null,2] 

示例 2:

输入:root = [3,0,4,null,2,null,null,1], low = 1, high = 3

输出:[3,2,null,1] 

问题分析:

当遍历到节点不在范围内,需删除。此时不能return null,而是要继续遍历此节点的子树。例如

if (root.val<low)    return root.right;//错误写法

 当删除0后,需要继续向右子树遍历,不能直接return root.right,因为可能会有比low小的节点1也直接返回给了7的左子树方向

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);//当此时的节点小于low,就把右子树(有可能小于low,所以需要递归判断每个节点)放到上一个节点
            return right;
        }
        if (root.val>high){
            TreeNode left=trimBST(root.left,low,high);//当此时的节点大于high,就把左子树(有可能大于high,所以需要递归判断每个节点)放到上一个节点
            return left;
        }

        root.left=trimBST(root.left,low,high);//接收下一层的节点
        root.right=trimBST(root.right,low,high);//接收下一层的节点
        return root;

    }
}

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

给你一个整数数组 nums ,其中元素已经按 升序 排列,请你将其转换为一棵 高度平衡 二叉搜索树。

高度平衡 二叉树是一棵满足「每个节点的左右两个子树的高度差的绝对值不超过 1 」的二叉树。

示例 1:

输入:nums = [-10,-3,0,5,9]

输出:[0,-3,9,-10,null,5]

解释:[0,-10,5,null,-3,null,9] 也将被视为正确答案: 

示例 2:

输入:nums = [1,3]

输出:[3,1]

解释:[1,null,3] 和 [3,1] 都是高度平衡二叉搜索树。 

问题分析:

找中间节点,然后分出左区间和右区间,左闭右闭。

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 node=new TreeNode(nums[mid]);
        node.left=traversal(nums,left,mid-1);
        node.right=traversal(nums,mid+1,right);
        return node;
    }
}

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

给出二叉 搜索 树的根节点,该树的节点值各不相同,请你将其转换为累加树(Greater Sum Tree),使每个节点 node 的新值等于原树中大于或等于 node.val 的值之和。

提醒一下,二叉搜索树满足下列约束条件:

  • 节点的左子树仅包含键 小于 节点键的节点。
  • 节点的右子树仅包含键 大于 节点键的节点。
  • 左右子树也必须是二叉搜索树。

示例 1:

输入:[4,1,6,0,2,5,7,null,null,null,3,null,null,null,8]

输出:[30,36,21,36,35,26,15,null,null,null,33,null,null,null,8]   

示例 2:

输入:root = [0,null,1]

输出:[1,null,1]   

示例 3:

输入:root = [1,0,2]

输出:[3,3,2]

示例 4:

输入:root = [3,2,4,1]

输出:[7,9,4,10]

问题分析:

 二叉搜索树左中右为正序,但是本题从倒序开始相加,也就是从最大的数开始相加,所以遍历顺序为右中左。定义双指针pre和cur,pre为int型,若是TreeNode型会引起空指向,用int会比较方便。

class Solution {
    int pre=0;//定义前一个节点的数值
    public TreeNode convertBST(TreeNode root) {
        traversal(root);
        return root;
    }
    public void traversal(TreeNode cur){//只是改树的节点的值,无返回值
        if (cur==null) return;
        traversal(cur.right);//右

        if (pre!=0){//中
            cur.val=cur.val+pre;
        }
        pre=cur.val;

        traversal(cur.left);//左
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值