代码随想录算法训练营第二十天|654. 最大二叉树、617.合并二叉树、700. 二叉搜索树中的搜索、98. 验证二叉搜索树。

654. 最大二叉树

题目链接:最大二叉树

题目描述
给定一个不重复的整数数组 nums 。 最大二叉树 可以用下面的算法从 nums 递归地构建:
创建一个根节点,其值为 nums 中的最大值。
递归地在最大值 左边 的 子数组前缀上 构建左子树。
递归地在最大值 右边 的 子数组后缀上 构建右子树。
返回 nums 构建的 最大二叉树 。

解题思路
本题解题思路确定递归三部曲即可很好的解题
第一步:确定递归函数的参数和返回值
传入参数:传入需要构建的数组
返回值:返回根节点
第二步:确定终止条件
终止条件:递归到单个节点,也就是叶子节点时返回。
第三步:确定单层递归的逻辑
单层逻辑先找到数组最大值然后赋予根节点
然后根据根节点的下标划分左子树和右子树的数组范围。

代码实现

class Solution {
    public TreeNode constructMaximumBinaryTree(int[] nums) {
        TreeNode root = new TreeNode();
        if (nums.length == 1) {
            root.val = nums[0];
            return root;
        }
        int max = 0;
        int maxIndex = 0;
        for (int i = 0; i < nums.length; i++) {// 找到最大元素的位置和值
            if (nums[i] > max) {
                max = nums[i];
                maxIndex = i;
            }
        }
        root.val = nums[maxIndex];
        // 构建左子树
        if (maxIndex > 0) {
            int[] left = new int[maxIndex];
            for (int i = 0; i < maxIndex; i++) {
                left[i] = nums[i];
            }
            root.left = constructMaximumBinaryTree(left);
        }
        // 构建右子树
        if (maxIndex < nums.length - 1) {
            int[] right = new int[nums.length - maxIndex - 1];
            int j = maxIndex + 1;
            for (int i = 0; i < nums.length - maxIndex - 1; i++) {
                right[i] = nums[j++];
            }
            root.right = constructMaximumBinaryTree(right);
        }
        return root;
    }
}

617.合并二叉树

题目链接:合并二叉树

题目描述
给你两棵二叉树: root1 和 root2 。
想象一下,当你将其中一棵覆盖到另一棵之上时,两棵树上的一些节点将会重叠(而另一些不会)。你需要将这两棵树合并成一棵新二叉树。合并的规则是:如果两个节点重叠,那么将这两个节点的值相加作为合并后节点的新值;否则,不为 null 的节点将直接作为新二叉树的节点。
返回合并后的二叉树。
注意: 合并过程必须从两个树的根节点开始。

解题思路
递归三部曲:
1.确定递归函数的参数和返回值:
传入参数:两棵树节点
返回值:合并后的根节点
2.确定终止条件:
终止条件为两棵树有一课为空或全为空
返回另一个不为空的;
3.确定单层递归的逻辑:
先将两棵树根节点合并
之后递归左子树和右子树。

迭代法的实现方法为使用层序遍历法一次遍历两个节点,对两个节点进行操作即可。
代码实现
递归法

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;
    }
}

迭代法

class Solution {
    public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
        if (root1 == null) {
            return root2;
        }
        if (root2 == null) {
            return root1;
        }
        Queue<TreeNode> que = new LinkedList<>();
        que.offer(root1);
        que.offer(root2);
        while (!que.isEmpty()) {
            TreeNode node1 = que.poll();
            TreeNode node2 = que.poll();
            node1.val += node2.val;
            //两者都不空则加入队列进行下次循环
            if (node1.left != null && node2.left != null) {
                que.offer(node1.left);
                que.offer(node2.left);
            }
            if (node1.right != null && node2.right != null) {
                que.offer(node1.right);
                que.offer(node2.right);
            }
            //1空2不空则直接将2赋予1
            if (node1.left == null && node2.left != null) {
            }
            if (node1.right == null && node2.right != null) {
                node1.right = node2.right;
            }
            //1不空2空则可以不做操作
        }
        return root1;
    }
}

700. 二叉搜索树中的搜索

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

题目描述
给定二叉搜索树(BST)的根节点 root 和一个整数值 val。
你需要在 BST 中找到节点值等于 val 的节点。 返回以该节点为根的子树。 如果节点不存在,则返回 null 。

解题思路
本题只要了解二叉搜索树左子树小于根节点,右子树大于根节点,按照这个大小关系进行递归和遍历就会很简单。val大于当前值则递归右子树,小于则递归左子树。迭代法同理。

代码实现
递归法

class Solution {
    public TreeNode searchBST(TreeNode root, int val) {
        if(root==null||root.val == val){
            return root;
        }
        TreeNode res = new TreeNode();
        if(val>root.val){
            res = searchBST(root.right,val);
        }
        if(val<root.val){
            res = searchBST(root.left,val);
        }
        return res;
    }
}

迭代法

class Solution {
    public TreeNode searchBST(TreeNode root, int val) {
        while(root!=null){
            if(val==root.val){
                return root;
            }
            if(val>root.val){
                root=root.right;
            }else if(val<root.val){
                root= root.left;
            }
        }
        return root;
    }
}

98. 验证二叉搜索树

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

题目描述
给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。
有效 二叉搜索树定义如下:
节点的左子树只包含 小于 当前节点的数。
节点的右子树只包含 大于 当前节点的数。
所有左子树和右子树自身必须也是二叉搜索树。

解题思路
要知道中序遍历下,输出的二叉搜索树节点的数值是有序序列。
有了这个特性,验证二叉搜索树,就相当于变成了判断一个序列是不是递增的了。
所以本题最好使用中序遍历来解答,利用中序遍历判断这个序列是不是递增的即可。

代码实现
递归法

class Solution {
    TreeNode max;//记录当前节点父节点的值

    public boolean isValidBST(TreeNode root) {
        if (root == null) {
            return true;
        }
        // 左子树
        boolean left = isValidBST(root.left);
        if (!left) {
            return false;
        }

        // 根节点
        if (max != null && root.val <= max.val) {
            return false;
        }
        max = root;

        // 右子树
        boolean right = isValidBST(root.right);
        return right;
    }
}

迭代法

class Solution {
    public boolean isValidBST(TreeNode root) {
        if (root == null) {
            return true;
        }
        Stack<TreeNode> sta = new Stack<>();
        TreeNode node = null;
        while (root != null || !sta.isEmpty()) {
            while (root != null) {//中序遍历先最左下节点
                sta.push(root);
                root = root.left;
            }
        
            // 中
            TreeNode pop = sta.pop();
            if(node!=null &&pop.val<=node.val){
                return false;
            }
            node = pop;
            
            //右
            root= pop.right;
        }
        return true;
    }
}

你可能感兴趣的:(算法)