代码随想录第二十天

代码随想录第二十天

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

Leetcode 654. 最大二叉树

题目链接: 最大二叉树
自己的思路:没想到!!!!

正确思路:先学递归!!构造二叉树都是用前序遍历,因为要先构造中间结点,在构造中间节点的左右节点,在一定区间[l,r]上进行最大值的寻找,然后以此索引为界,递归构造左右结点;递归三部曲:1、终止条件:如果此数组不合法,直接返回空;2、传入参数:数组以及左右区间的临界点;3、单层逻辑:先处理中节点,找到当前数组区间的最大值,然后构造当前节点,然后左右进行递归,返回此节点!!!!

代码:

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

    public TreeNode bulid(int[] nums,int l,int r){
        //左索引大于右索引时,直接返回空
        if (l>r) return null;
        //记录最大值的索引
        int index = l;
        for (int i =l;i<=r;i++){
            if (nums[i]>nums[index]) index = i; 
        }
        TreeNode node = new TreeNode(nums[index]);
        //左右递归
        node.left = bulid(nums,l,index-1);
        node.right = bulid(nums,index+1,r);
        //返回当前节点
        return node;
    }
}

复杂度分析
时间复杂度: O ( n 2 ) \mathcal{O}(n^2) O(n2)
空间复杂度: O ( 1 ) \mathcal{O}(1) O(1)

Leetcode 617. 合并二叉树

题目链接: 合并二叉树
自己的思路:没想到!!!

正确思路:构造二叉树要用前序遍历!!!!以root1为新树的结点;递归三部曲:1、输入参数:之前两个节点的根节点;2、终止条件:当子树1为空时,返回子树2,否则返回子树1;3、单层逻辑:将子树1和子树2的值都加到子树1上作为新树的根节点,然后构造子树1的左右结点,然后返回子树1的节点即可!!!!

代码:

class Solution {
    public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
        //终止条件:左节点为空或者右结点为空
        if (root1==null||root2==null){
            return root1==null?root2:root1;
        }
        //以root1为主要节点,将两个节点的值加到root1节点上
        root1.val = root1.val + root2.val;
        //左右递归
        root1.left = mergeTrees(root1.left,root2.left);
        root1.right = mergeTrees(root1.right,root2.right);
        return root1;
    }
}

复杂度分析
时间复杂度: O ( n ) \mathcal{O}(n) O(n)
空间复杂度: O ( n ) \mathcal{O}(n) O(n)

Leetcode 700. 二叉搜索树中的搜索

题目链接: 二叉搜索树中的搜索
自己的思路:迭代来找,利用二叉树搜索树的特点,如果当前结点的值大于val,则向左找,如果当前结点的值小于val,则向右找,否则返回当前结点!!!

正确思路:迭代、递归!!!

迭代代码:

class Solution {
    public TreeNode searchBST(TreeNode root, int val) {

        while(root!=null){
            //当前结点值大于val,则向左找
            if (root.val>val){
                root = root.left;
            //当前结点值小于val,则向右找
            }else if (root.val<val){
                root = root.right;
            }else{
                return root;
            }
        }
        return root;
    }
}

复杂度分析
时间复杂度: O ( n ) \mathcal{O}(n) O(n)
空间复杂度: O ( 1 ) \mathcal{O}(1) O(1)

递归代码:

class Solution {
    public TreeNode searchBST(TreeNode root, int val) {
        //终止递归
        if (root==null) return null;
        //前序遍历
        if (root.val==val) return root;
        else if (root.val>val) return searchBST(root.left,val);
        else return searchBST(root.right,val);
    }
}

复杂度分析
时间复杂度: O ( n ) \mathcal{O}(n) O(n)
空间复杂度: O ( 1 ) \mathcal{O}(1) O(1)

Leetcode 98. 验证二叉搜索树

题目链接: 验证二叉搜索树
自己的思路:没想到!!!!
正确思路:最简单的思路是使用一个值来记录之前所有元素的最大值,然后进行中序遍历,因为这样可以保证数据是递增的,但是这样做有一个缺点就是可能之前树中的节点就是long或者int的最小值,直接就返回false了,所以我们采用临时变量记录上一个结点,用这个节点和上一个节点表示,如果大于上一个节点,正常运行,1否则返回false;递归三部曲:1、终止条件:当结点为空,返回true;2、传入参数:当前节点;3、单层逻辑:左递归,然后判断中间节点和上一个节点的关系,再右递归,最后返回左递归和右递归的并即可!!!!

代码:

class Solution {
    Integer pre;
    public boolean isValidBST(TreeNode root) {
        if (root==null) return true;
        boolean left = isValidBST(root.left);
        //如果当前节点值小于上一个节点值,证明不是二叉搜索树
        if (pre!=null&&pre>=root.val){
            return false;
        }
        //记录上一个节点值
        pre = root.val;
        boolean right = isValidBST(root.right);
        return left&&right;
    }
}

复杂度分析
时间复杂度: O ( n ) \mathcal{O}(n) O(n)
空间复杂度: O ( 1 ) \mathcal{O}(1) O(1)

你可能感兴趣的:(数据结构,算法,java,开发语言)