算法修炼Day23|● 669. 修剪二叉搜索树 ● 108.将有序数组转换为二叉搜索树 ● 538.把二叉搜索树转换为累加树

93 阅读1分钟

LeetCode:669. 修剪二叉搜索树 - 力扣(LeetCode)

1.思路

比较当前节点值与区间值,将目标区间左侧和右侧的进行递归排除(排除法),比如:如果root.val<low,则向右递归判断该节点右子树是否在区间内?如果root.val>high,则向左递归判断该节点左子树是否符合目标区间,返回符合条件的节点。

2.代码实现
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;
    }
}
3.复杂度分析

时间复杂度:O(n).

空间复杂度:O(n).

LeetCode:108. 将有序数组转换为二叉搜索树 - 力扣(LeetCode)

1.思路

注意审题!高度平衡二叉搜索树 构造新的方法,进行前序递归遍历,每次构建从根节点展开。终止条件很关键:[left, right]区间不合法时终止,选择的左闭右闭,所以left<right时不合法。

2.代码实现
class Solution {
    public TreeNode sortedArrayToBST(int[] nums) {
        TreeNode root = traversal(nums, 0, nums.length - 1);
        return root;
    }

    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;
    }
}
3.复杂度分析

时间复杂度:O(n).

空间复杂度:O(logn).

LeetCode:538. 把二叉搜索树转换为累加树 - 力扣(LeetCode)

1.思路

双指针+递归法 右-》中-》左的遍历顺序

2.代码实现
class Solution {
    int pre;
    public TreeNode convertBST(TreeNode root) {
        pre = 0;
        traversal(root);
        return root;
    }

    public void traversal(TreeNode root) {
        // 终止
        if (root == null) return;
        // 右
        traversal(root.right);
        // 中
        pre += root.val;
        root.val = pre;
        // 左
        traversal(root.left);
    }
}
3.复杂度分析

时间复杂度:O(n).每个节点遍历一次。

空间复杂度:O(n).平均为O(logn),最坏情况为O(n).