代码随想录算法训练营Day23|LC669 修剪二叉搜索树&LC108 将有序数组转化为二叉搜索树&LC538 把二叉搜索树转换为累加树

本文介绍了如何使用递归方法解决三个与二叉搜索树相关的问题:修剪二叉搜索树(保持搜索性质),将有序数组转换为二叉搜索树(保持中序遍历递增),以及将二叉搜索树转换为累加树(利用后缀和思想)。
摘要由CSDN通过智能技术生成

一句话总结:题不太难,写起来有点费劲。

原题链接:669 修剪二叉搜索树

用递归的写法比较轻松。按照代码随想录的递归三部曲理论,首先要找好递归的返回值及其传入参数。然后是找好递归的出口,即root == null时return root。最后是确定单层递归的逻辑。这里就是如果当前节点值小于下界low,则返回修剪后的右子树即可。反之则返回当前节点的左子树。而默认条件,即当前节点值在上下界之间的话,则该节点的左指针指向修剪后的左子树,右指针指向修剪后的右子树。最后返回根节点即可(该根节点不一定是原本树的根节点)。

class Solution {
    public TreeNode trimBST(TreeNode root, int low, int high) {
        if (root == null) return root;
        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;
    }
}

 原题链接:108 将有序数组转换为二叉搜索树

这题就很简单了。利用递归三部曲,首先确定传入参数以及返回值类型。返回值类型明显是一棵树的根节点,传入参数只有一个数组,那么怎么找到这个所求的二叉搜索树的根节点值很明显还需要确定其值在数组中的位置。所以额外设计一个同名函数,另外传入两个参数,值为数组的左右端点值,在递归过程中,它们将不断迭代为子树的左右端点。

然后是确定递归出口。这题类似于二分查找的逻辑,所以在left > right时,返回空节点即为递归出口。

最后是确定单层递归逻辑。对于此题来说,每一轮中都会对当前找到的节点值构建一个新的节点,然后其左右指针指向其利用递归函数构建的新节点。而其找到当前节点的值的逻辑同二分查找。

class Solution {
    public TreeNode sortedArrayToBST(int[] nums) {
        return sortedArrayToBST(nums, 0, nums.length - 1);
    }

    private TreeNode sortedArrayToBST(int[] nums, int start, int end) {
        if (start > end) return null;
        int mid = start + (end - start) / 2;
        TreeNode root = new TreeNode(nums[mid]);
        root.left = sortedArrayToBST(nums, start, mid - 1);
        root.right = sortedArrayToBST(nums, mid + 1, end);
        return root;
    }
}

 原题链接:538 把二叉搜索树转换为累加树

这题的题面乍一看很类似于后缀和。在实际解题时确实利用到了后缀和思想,同时也二叉搜索树的性质,即其中序遍历序列是一个递增数组。因此,考虑到要先对二叉搜索树中值最大的节点进行处理,设计的递归逻辑也是先递归地处理右节点,然后处理当前值,再去递归地处理左节点。

class Solution {
    int sufSum = 0;
    public TreeNode convertBST(TreeNode root) {
        // 前缀和思想,利用二叉树的性质,从右往左遍历        
        if (root != null) {
            convertBST(root.right);
            sufSum += root.val;
            root.val = sufSum;
            convertBST(root.left);  
        }
        return root;        
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值