(JAVA)Leetcode 最大二叉树 二叉搜索树中的搜索 验证二叉搜索树

最大二叉树

给定一个不含重复元素的整数数组。一个以此数组构建的最大二叉树定义如下:

  • 二叉树的根是数组中的最大元素。
  • 左子树是通过数组中最大值左边部分构造出的最大二叉树。
  • 右子树是通过数组中最大值右边部分构造出的最大二叉树。

通过给定的数组构建最大二叉树,并且输出这个树的根节点。

采用前序遍历 先构造中间节点 然后递归构造左子树和右子树

  1. 确定递归函数的参数和返回值

      参数:存放元素的数组 数组的最左边 数组的最右边

      返回值:返回该数组构造的二叉树的头结点 返回类型是指向节点的指针

     2.确定终止条件

      因为输入的数组大小一定是大于等于1的

      所以当递归遍历的时候传入的数组大小为1,说明遍历到叶子节点了

      方法:定义一个新节点,并把这个数组的数值赋给新的节点,然后返回这个节点

     3.确定单层递归的逻辑

  1. 先找到数组中最大的值和对应的下标,最大的值构造根节点,下标用来下一步分割数组。(该题与前两题从中序和后序遍历序列构造二叉树类似
  2. 最大值所在的下标左区间构造左子树
  3. 最大值所在的下标右区间构造右子树

注意:此题用左闭右开型

完整代码如下:

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

    public TreeNode constructMaximumBinaryTree1(int[] nums, int leftIndex, int rightIndex) {
        if (rightIndex - leftIndex < 1) {// 没有元素了
            return null;
        }
        if (rightIndex - leftIndex == 1) {// 只有一个元素
            return new TreeNode(nums[leftIndex]);
        }
        int maxIndex = leftIndex;// 最大值所在位置
        int maxVal = nums[maxIndex];// 最大值
        for (int i = leftIndex + 1; i < rightIndex; i++) {
            if (nums[i] > maxVal){
                maxVal = nums[i];
                maxIndex = i;
            }
        }
        TreeNode root = new TreeNode(maxVal);
        // 根据maxIndex划分左右子树
        root.left = constructMaximumBinaryTree1(nums, leftIndex, maxIndex);
        root.right = constructMaximumBinaryTree1(nums, maxIndex + 1, rightIndex);
        return root;
    }
}

二叉搜索树中的搜索

二叉搜索树的性质决定了其递归遍历迭代遍历与普通二叉树不同。

递归法

  1. 确定递归函数的参数和返回值

      参数:根节点和要搜索的数值

      返回值:以这个搜索数值所在的节点

    2.确定终止条件

      若root为空或找到数值后,返回root节点

   3.确定单层递归的逻辑

      因为二叉搜索树的节点是有序的,所以可以有方向的去搜索。

      若(val<root.val) 搜索左子树   若(val>root.val) 搜索右子树

因为搜索到目标节点了,就要立即return了,这样才是找到节点就返回(搜索某一条边),如果不加return,就是遍历整棵树了

迭代法

普通二叉树可用栈来模拟深度遍历  可用队列来模拟广度遍历

而二叉搜索树由于结点的有序性,可以不用辅助栈或队列就可以写出迭代法。

注意:二叉搜索树不需要回溯的过程,因为节点的有序性就帮我们确定了搜索方向。

完整代码如下:

递归法

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

    }
}

迭代法

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

验证二叉搜索树

思路:中序遍历下,输出的二叉搜索树节点的数值是有序序列。

      有了这个特性,验证二叉树就相当于变成了判断一个序列是否是递增的。

递归法

  1. 确定递归函数参数以及返回值

       参数:TreeNode root

       返回值:bool型    如果找不到符合的节点就立刻返回

  1. 确定终止条件

       空节点也是二叉搜索树

  1. 确定单层递归的逻辑

       中序遍历,一直更新maxValue

       若发现maxValue>=root.val 就返回false 元素相同时也要返回false

迭代法

模拟二叉树中序遍历,只需要稍加改动。

完整代码如下:

递归法

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> stack=new Stack<>();
        TreeNode pre=null;
        while(root!=null||!stack.isEmpty()){
            while(root!=null){
                stack.push(root);
                root=root.left;
            }
            TreeNode node =stack.pop();
            if(pre!=null && node.val<=pre.val){
                return false;
            }
            pre=node;
            root=node.right;
        }
        return true;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值