day20 打卡654.最大二叉树 617.合并二叉树 700.二叉搜索树中的搜索

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

654.最大二叉树

654题目链接

1.看了视频链接之后按照思路写的。

class Solution {
    public TreeNode constructMaximumBinaryTree(int[] nums) {
        if (nums == null || nums.length == 0) return null;
        if (nums.length == 1) return new TreeNode(nums[0], null, null);

        // 从数组里找到最大值以及它的下标
        int maxVal = Integer.MIN_VALUE;
        int index = 0;
        for (int i = 0 ; i<nums.length ; i++) {
            if (nums[i] > maxVal) {
                maxVal = nums[i];
                index = i;
            }
        }

        TreeNode cur = new TreeNode(nums[index]);

        // 分割左右子树对应的数组
        int[] leftNums = new int[index];
        int[] rightNums = new int[nums.length-1-index];
        int rightIndex = 0;
        for (int i = 0 ; i<nums.length ; i++) {
            if (i<index) {
                leftNums[i] = nums[i];
            } else if (i>index) {
                rightNums[rightIndex++] = nums[i];
            }
        }

        cur.left = constructMaximumBinaryTree(leftNums);
        cur.right = constructMaximumBinaryTree(rightNums);

        return cur;
    }
}

2.改进效率。注意一开始我写成constructMaximumBinaryTree(nums, 0, nums.length-1),因为constructMaximumBinaryTree(int[] nums, int leftIndex, int rightIndex)是左闭右开。所以下标nums.length-1是不对的,这个是取的到的。我们要用nums.length,这个是取不到的。

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

    // 左闭右开
    public TreeNode constructMaximumBinaryTree(int[] nums, int leftIndex, int rightIndex) {
        // 没有一个元素
        if (rightIndex - leftIndex < 1) return null;
        // 只有一个元素
        if (rightIndex - leftIndex == 1) return new TreeNode(nums[leftIndex], null, null);

        // 找到范围数组中最大的元素以及下标
        int maxVal = nums[leftIndex];
        int index = leftIndex;
        for (int i = leftIndex+1 ; i<rightIndex ; i++) {
            if (nums[i] > maxVal) { 
                maxVal = nums[i];
                index = i;
            }
        }  

        // 设置中间节点
        TreeNode cur = new TreeNode(maxVal);

        // 设置中间节点的左子树
        cur.left = constructMaximumBinaryTree(nums, leftIndex, index);
        // 设置中间节点的右子树
        cur.right = constructMaximumBinaryTree(nums, index+1, rightIndex);

        return cur;
    }
}

617.合并二叉树

617题目链接

1.递归法

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

700.二叉搜索树中的搜索

700题目链接

1.递归法

class Solution {
    public TreeNode searchBST(TreeNode root, int val) {
        if (root == null) return null;
        if (root.val == val) return root;

        TreeNode left = searchBST(root.left, val);
        if (left != null) return left;

        TreeNode right = searchBST(root.right, val);
        if (right != null) return right;

        return null;
    }
}

2.迭代法

class Solution {
    public TreeNode searchBST(TreeNode root, int val) {
        if (root == null) return null;
        Queue<TreeNode> que = new LinkedList<>();
        que.offer(root);
        while (!que.isEmpty()) {
            int size = que.size();

            while (size-->0) {
                TreeNode cur = que.poll();
                if (cur.val == val) return cur;
                if (cur.left != null) que.offer(cur.left);
                if (cur.right != null) que.offer(cur.right);
            }
        }
        return null;
    }
}

98.验证二叉搜索树

98题目链接

需要用到的一个特性:二叉搜索树的中序遍历(左中右)是递增的

如下二叉树:

​ 10

​ 05 15

​ 11 20

中序遍历是:05, 10, 11, 15, 20

1.递归法——借助maxVal的帮助

class Solution {
    long maxVal = Long.MIN_VALUE;
    
    public boolean isValidBST(TreeNode root) {
        if (root == null) return true;
        // 左
        boolean left = isValidBST(root.left);
        // 中
        if (maxVal < root.val) {
            maxVal = root.val;
        } else {
            return false;
        }
        // 右
        boolean right = isValidBST(root.right);

        return left && right;
    }
}

2.递归法——借助前一个指针的帮助

class Solution {
    TreeNode pre = null;
    
    public boolean isValidBST(TreeNode root) {
        if (root == null) return true;

        boolean left = isValidBST(root.left);

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

        boolean right = isValidBST(root.right);

        return left && right;
    }
}

3.迭代法

class Solution {
    public boolean isValidBST(TreeNode root) {
        if (root == null) return true;
        Stack<TreeNode> stack = new Stack<>();
        TreeNode cur = root;
        TreeNode pre = null;

        while (cur != null || !stack.isEmpty()) {
            if (cur != null) {
                stack.push(cur);
                cur = cur.left;
            } else {
                cur = stack.pop();
                if (pre != null && pre.val >= cur.val) {
                    return false;
                }
                pre = cur;
                cur = cur.right;
            }
        }
        return true;
    }
}

参考资料

代码随想录

posted @ 2023-03-20 16:40  zzzzzzsl  阅读(22)  评论(0)    收藏  举报