代码随想录算法训练营第20天

今日任务

● 654.最大二叉树 ● 617.合并二叉树 ● 700.二叉搜索树中的搜索 ● 98.验证二叉搜索树

链接:https://docs.qq.com/doc/DUGFRU2V6Z1F4alBH (opens in a new tab)

654.最大二叉树

自己想法

class Solution {
    public TreeNode constructMaximumBinaryTree(int[] nums) {
        return invert(nums, 0, nums.length);
    }
    // 1.返回值:当前子树的根节点。参数:子数组首尾(前闭后开)
    public TreeNode invert(int[] nums, int start, int end) {
        // 2.结束条件
        if(start == end) return null;
        // 3.递归逻辑
        // 3.1.找最大(及其索引号),new节点
        int max = findMax(nums, start, end);
        TreeNode root = new TreeNode(nums[max]);
        // 3.2.左右递归
        root.left = invert(nums, start, max);
        root.right = invert(nums, max + 1, end);
        // 3.3.返回节点
        return root;
    }
    public int findMax(int[] nums, int start, int end) {
        int max = start;
        for(int i = start; i < end; i++) {
            if(nums[i] > nums[max]) max = i;
        }
        return max;
    }
}

617.合并二叉树

自己想法

class Solution {
    public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
        return invert(root1, root2);
    }
    // 1.返回值:合并当前节点下面的子树的结果
    public TreeNode invert(TreeNode root1, TreeNode root2) {
        // 2.结束条件:至少有一方为null,则返回不为null的一方,否则直接返回null
        if(root1 == null) return root2;
        if(root2 == null) return root1;
        // 3.递归逻辑:都不为null
        // 3.1.new,加和节点数值
        TreeNode root = new TreeNode(root1.val + root2.val);
        // 3.2.再递归左右
        root.left = invert(root1.left, root2.left);
        root.right = invert(root1.right, root2.right);
        // 3.3.返回节点
        return root;
    }
}

700.二叉搜索树中的搜索

自己想法

class Solution {
    public TreeNode searchBST(TreeNode root, int val) {
        // node表示当前查看的节点
        TreeNode node = root;
        // 循环:若当前node为null,则说明没有找到,结束循环
        while(node != null) {
            // 找到,循环break
            if(node.val == val) break;
            // 当前值小于待寻找值,找右边
            if(node.val < val) {
                node = node.right;
                continue;
            }
            // 当前值大于待寻找值,找左边
            if(node.val > val) {
                node = node.left;
                continue;
            }
        }
        // 找到返回该节点为根的子树,否则返回null
        return node;
    }
}

98.验证二叉搜索树

自己想法

二叉搜索树的中序一定是递增的

class Solution {
    public boolean isValidBST(TreeNode root) {
        List<Integer> inorder = new ArrayList<>();
        traversal(root, inorder);
        // 中序一定是递增的
        if(inorder.size() == 0) return true;
        for(int i = 1; i < inorder.size(); i++) {
            System.out.println(inorder.get(i) + ' ' + inorder.get(i - 1));
            if (inorder.get(i) <= inorder.get(i - 1)) return false;
        }
        return true;
    }
    public void traversal(TreeNode cur, List<Integer> inorder) {
        if(cur == null) return;
        traversal(cur.left, inorder);
        inorder.add(cur.val);
        traversal(cur.right, inorder);
    }
}

注意坑:不能单纯的比较左节点小于中间节点,右节点大于中间节点就完事了。

以下代码无法正确判断上图情况

class Solution {
    public boolean isValidBST(TreeNode root) {
        return invert(root, null, -1);
    }
    public boolean invert(TreeNode root, Integer parent, int direction) {
        // 2.结束条件:
        if(root == null) return true;
        // 3.递归逻辑
        if((root.left != null && root.left.val >= root.val) 
        || (root.right != null && root.right.val <= root.val)) return false;
        else return invert(root.left, root.val, 1) && invert(root.right, root.val, 2);
    }
}

但是可以修改参数,传入min和max,来判断是否在范围内

class Solution {
    public boolean isValidBST(TreeNode root) {
        return isValidBST(root, null, null);
    }
 
    public boolean isValidBST(TreeNode root, TreeNode min, TreeNode max) {
        if (root == null) {
            return true;
        }
        if (min != null && root.val <= min.val) {
            return false;
        }
        if (max != null && root.val >= max.val) {
            return false;
        }
        return isValidBST(root.left, min, root) && isValidBST(root.right, root, max);
    }
}