判断一个二叉树是不是合法的二分查找树
来源:互联网 发布:巴丁算法集 编辑:程序博客网 时间:2024/05/01 05:36
leetcode题目https://leetcode.com/problems/validate-binary-search-tree/,判断一个二叉树是不是合法的二分查找树,这个题目应该说遇到多次了,然而在写的时候还是费了一番时间,而且写了一个十分拙劣的算法(在本文最后,不做解释)。
参考leetcode的discuss,遇到了两个比较好的解法,一个是递归(同样是递归,人家的就很简单),另一个非递归。
先看递归,递归的话采用自顶向下的方式比较简单,自顶向下,也就是自父节点向子节点传递范围要求(子节点不能大于某个值,不能小于某个值),比自底向上要方便的多,看代码,采用Long.MIN_VALUE是防止根节点是Integer.MIN_VALUE,那就通不过了:
/* 判断一个二叉树是不是合法的二分查找树的简单的递给方法,学习 * 采用自顶向下的遍历方式,对于每个节点,检查顶部传来的范围要求, * 要求是指:对于左子树,父节点的值就是最大值,对于右子树,父节点的值就是最小值 */ public boolean isValidBST(TreeNode root) { //初始的时候,对根节点没有范围要求 return isValidBST(root, Long.MIN_VALUE, Long.MAX_VALUE); } public boolean isValidBST(TreeNode root, long minVal, long maxVal) { if (root == null) return true; //检查是否满足根节点的范围要求 if (root.val >= maxVal || root.val <= minVal) return false; //修改对子节点的要求,对于左子树,本节点的值就是最大值,对于右子树,本节点的值就是最小值 return isValidBST(root.left, minVal, root.val) && isValidBST(root.right, root.val, maxVal); }
再看非递归,非递归的方式比递归的方式速度要慢,但是很明显非递归能有效的减小栈空间的使用量,防止栈溢出。思路是使用中序非递归遍历(这里有二叉树的非递归中序遍历),跟中序非递归遍历基本完全一致,就是保存了一个前驱节点,并在每次访问一个节点的时候更新前驱节点,如果前驱节点的值大于等于当前节点,那就是非二分查找树,因为二分查找树的中序遍历是一个递增序列。看代码:
/*判断一个二叉树是不是合法的二叉树的非递归遍历 * 采用中序遍历,并保存一个前驱节点,这样在每检查一个 * 节点的时候,就跟前驱节点对比,如果比前驱节点小(或者等于) * 就表示不合法 */ public boolean isValidBST(TreeNode root){ Stack<TreeNode> stack = new Stack<TreeNode>(); //设置前驱节点 TreeNode pre = null; while(root!=null || !stack.isEmpty()){ while(root!=null){ //将当前节点,以及左子树一直入栈,循环结束时,root==null stack.push(root); root = root.left; } root = stack.pop(); //比较并更新前驱,与普通遍历的区别就在下面四行 if(pre!=null && root.val<= pre.val){ return false; } pre = root; root = root.right; //访问右子树 } return true; }
我的拙劣的算法:
public boolean isValidBST(TreeNode root) { if(root==null){ return true; } int[] minMax = new int[2]; return minMax(root, minMax); } public boolean minMax(TreeNode root,int[] minMax){ if(root!=null&&root.left==null&&root.right==null){ minMax[0] = root.val; minMax[1] = root.val; return true; } int[] left = null; int[] right = null; if(root.left!=null){ left = new int[2]; boolean bin = minMax(root.left, left); if(!bin){ return false; } } if(root.right!=null){ right = new int[2]; boolean bin = minMax(root.right,right); if(!bin){ return false; } } if((left==null||left!=null&&root.val>left[1]) &&(right==null||right!=null&&root.val<right[0])){ if(left!=null&&right!=null){ minMax[0] = Math.min(Math.min(left[0], right[0]),root.val); minMax[1] = Math.max(Math.max(left[1], right[1]),root.val); }else if(left!=null){ minMax[0] = Math.min(left[0],root.val); minMax[1] = Math.max(left[1],root.val); }else{ minMax[0] = Math.min(right[0],root.val); minMax[1] = Math.max(right[1],root.val); } return true; } return false; }
0 0
- 判断一个二叉树是不是合法的二分查找树
- 判断一个树是不是二叉查询树
- 判断一个树是不是二叉平衡树
- 判断一个树是不是平衡二叉树
- 判断一个树是不是平衡二叉树
- 判断一个树是不是平衡二叉树
- 判断一个二叉树是不是平衡的(算法)
- 剑指offer15--判断一个二叉树是不是另一个的子树
- 判断一颗二叉树是不是查找二叉树
- 判断二叉树是不是二叉查找树(BST)
- Validate Binary Search Tree--判断一个树是不是二叉查找树(重重重)
- JAVA 判断一个字符串是不是一个合法的日期格式
- JAVA 判断一个字符串是不是一个合法的日期格式
- JAVA 判断一个字符串是不是一个合法的日期格式
- JAVA 判断一个字符串是不是一个合法的日期格式
- JAVA 判断一个字符串是不是一个合法的日期格式
- 判断给定的二叉树是否为二分查找树
- java 判断一个二叉树是不是平衡二叉树
- springBoot集成mybatis
- ubuntu安装
- 查看硬盘UUID
- 非接触CPU卡外部认证步骤
- 数据库有数据,但查询不到
- 判断一个二叉树是不是合法的二分查找树
- 字体过长时,缩略并用省略号显示
- Android——MVP架构模式之入门demo
- OJ3403数据结构实验之排序六:希尔排序
- App Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure.
- 将图片处理成圆形
- 博客二三事
- Cmake简介和简单使用方法
- Android中使用Handler造成内存泄露的分析和解决