代码随想录Day20 | 654. 最大二叉树、617. 合并二叉数、700. 二叉搜索树中的搜索、 98. 验证二叉搜索树 | 二叉树、递归、BST

90 阅读2分钟

654. 最大二叉树

题目链接:654. 最大二叉树

思路: 函数 build 的定义是根据输入的数组构造最大二叉树,那么先要找到根节点,然后让 build 函数递归生成左右子树即可。数组中最大的数字是根结点,左边的树构成左子树,右边的数构成右子树

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

    TreeNode bulid(int[] nums, int l, int r) {
        if (l > r) return null;

        int max = Integer.MIN_VALUE;
        int index = -1;
        for (int i = l; i <= r; i++) {
            if (nums[i] >= max ) {
                max = nums[i];
                index = i;
            }
        }
        TreeNode root = new TreeNode(max);
        root.left = bulid(nums, l, index - 1);
        root.right = bulid(nums, index + 1, r);
        return root;
    }
}

总结:

617. 合并二叉数

题目链接:617. 合并二叉数

思路: 在root1上做合并操作,遍历两棵树,当其中一棵为空时,将另一棵的值赋给root1,如果都不为空,那么root1.val += root2.val。

class Solution {
    public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
        if (root1 == null) {
            return root2;
        }
        if (root2 == null) {
            return root1;
        }
        root1.val += root2.val;
        root1.left = mergeTrees(root1.left, root2.left);
        root1.right = mergeTrees(root1.right, root2.right);
        return root1;
    }
}

总结:

700. 二叉搜索树中的搜索

题目链接:700. 二叉搜索树中的搜索

思路:

第一思路穷举了所有节点,适用于所有二叉树。但没有充分利用 BST 的特殊性,没有把「左小右大」的特性用上。其实不需要递归地搜索两边,类似二分查找思想,根据 target 和 root.val 的大小比较,就能排除一边。

我的代码:

TreeNode searchBST(TreeNode root, int target);
    if (root == null) return null;
    if (root.val == target) return root;
    // 当前节点没找到就递归地去左右子树寻找
    TreeNode left = searchBST(root.left, target);
    TreeNode right = searchBST(root.right, target);

    return left != null ? left : right;
}

正确解法:

TreeNode searchBST(TreeNode root, int target) {
    if (root == null) {
        return null;
    }
    // 去左子树搜索
    if (root.val > target) {
        return searchBST(root.left, target);
    }
    // 去右子树搜索
    if (root.val < target) {
        return searchBST(root.right, target);
    }
    return root;
}

总结:

98. 验证二叉搜索树

题目链接:98. 验证二叉搜索树

思路:

第一思路以为根据BST 左小右大,只要检查 root.val > root.left.val 且 root.val < root.right.val 。问题在于,对于每一个节点 root,代码只检查了它的左右孩子节点是否符合左小右大的原则;但是根据 BST 的定义,root 的整个左子树都要小于 root.val,整个右子树都要大于 root.val。

我的代码:

class Solution {

    TreeNode pre;

    public boolean isValidBST(TreeNode root) {
        if (root == null) return true;
        
        boolean left = isValidBST(root.left);

        if (pre != null) {
            if (root.val <= pre.val) return false;
        }
        pre = root;

        boolean right = isValidBST(root.right);
        return left && right;
    }
}

总结: