题目:验证二叉搜索树

难度:Medium

题目内容

Given a binary tree, determine if it is a valid binary search tree (BST).

Assume a BST is defined as follows:

  • The left subtree of a node contains only nodes with keys less than the node's key.
  • The right subtree of a node contains only nodes with keys greater than the node's key.
  • Both the left and right subtrees must also be binary search trees.

翻译

给定一棵二叉树,确定它是否是一个有效的二叉搜索树(BST)。

BST的定义如下:

节点的左子树只包含小于节点键的键节点。

节点的右子树只包含大于节点键的键节点。

左和右子树都必须是二叉搜索树。

Example 1:

Input:
2
/ \
1 3
Output: true

Example 2:

    5
/ \
1 4
  / \
  3 6
Output: false

我的思路:搜索二叉树的验证就是要求每一个子树都是满足搜索树的“左小右大”的规定,

1、先判断自己作为根节点的左右二叉是否符合;

2、然后返回左右节点的递归结果的 “与” (全都符合才算符合)

我的代码

     public boolean isValidBST(TreeNode root) {
if (root == null) {
return true;
} if (root.left != null) {
TreeNode cur = root.left;
while (cur.right != null) {
cur = cur.right;
}
if (cur.val >= root.val) {
return false;
}
} if (root.right != null) {
TreeNode cur = root.right;
while (cur.left != null) {
cur = cur.left;
}
if (cur.val <= root.val) {
return false;
}
} return isValidBST(root.left) && isValidBST(root.right);
}

我的复杂度:O(N*logN)

编码过程中的问题

1、没仔细看题,而且记错搜索树的定义了,当出现两个值相等的时候,此时不是搜索树;

2、最开始只考虑到判断根节点和左右两个子节点就行了,结果后面案例跑错了,例如:

    5
/ \
1 6
  / \
  3 7 每个子树都是正确的二叉搜索树,但是整体上看,5的右子树内有比它小的3,所以此树不是二叉搜索树。

此时想到二叉树删除算法,当删除节点有两个子节点的时候,此时会选择此节点左节点的最右子系节点,或者右节点的最左子系节点进行代替,所以这两个节点值才是最接近根节点值的节点,所以每次的单个子树判断应该判断这两个,而不是左右子节点就行了。

答案代码

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

答案复杂度:O(N)

答案思路

也是利用了递归的思想,分别对每一个子树进行判断,但是它的亮点在于在判断的时候并不需要对子树进行搜索“最相近的值”,而是利用了“最大值”、“最小值”的思想:

对于每个子树,都有一个最大值和一个最小值,

对于左子树,最大值就是它的根节点的值,最小值是根节点的最小值(左父亲或者MIN_VALUE)

对于右子树,最小值就是它的根节点的值,最大值是根节点的最大值(右父亲或者MAX_VALUE)

例如:

   5
/ \
1 6
  / \
  3 7
5的满足小于最大值,大于最小值,然后递归(1,MIN,5) && 递归(4,5,MAX)
。。。
3节点的最大值为6,最小值应该为5,此时不满足,所以return false 其实还有一种非递归的解法:中序遍历,利用二叉搜索树中序遍历的有序性(在中序遍历的出栈时判断此值是否小于之前出栈的那个节点的值)
 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;
}
root = stack.pop();
if(pre != null && root.val <= pre.val) return false;
pre = root;
root = root.right;
}
return true;
}

注意:不能使用出栈值与栈顶进行比较,因为在中序遍历的过程中栈顶可能为空,所以此时无法比较。

 

LeetCode第[98]题(Java):Validate Binary Search Tree(验证二叉搜索树)的更多相关文章

  1. [CareerCup] 4.5 Validate Binary Search Tree 验证二叉搜索树

    4.5 Implement a function to check if a binary tree is a binary search tree. LeetCode上的原题,请参见我之前的博客Va ...

  2. [LeetCode] 98. Validate Binary Search Tree 验证二叉搜索树

    Given a binary tree, determine if it is a valid binary search tree (BST). Assume a BST is defined as ...

  3. [LeetCode] Validate Binary Search Tree 验证二叉搜索树

    Given a binary tree, determine if it is a valid binary search tree (BST). Assume a BST is defined as ...

  4. [LeetCode] 255. Verify Preorder Sequence in Binary Search Tree 验证二叉搜索树的先序序列

    Given an array of numbers, verify whether it is the correct preorder traversal sequence of a binary ...

  5. [leetcode]98. Validate Binary Search Tree验证二叉搜索树

    Given a binary tree, determine if it is a valid binary search tree (BST). Assume a BST is defined as ...

  6. 098 Validate Binary Search Tree 验证二叉搜索树

    给定一个二叉树,判断其是否是一个有效的二叉搜索树.一个二叉搜索树有如下定义:    左子树只包含小于当前节点的数.    右子树只包含大于当前节点的数.    所有子树自身必须也是二叉搜索树.示例 1 ...

  7. Leetcode98. Validate Binary Search Tree验证二叉搜索树

    给定一个二叉树,判断其是否是一个有效的二叉搜索树. 假设一个二叉搜索树具有如下特征: 节点的左子树只包含小于当前节点的数. 节点的右子树只包含大于当前节点的数. 所有左子树和右子树自身必须也是二叉搜索 ...

  8. [LeetCode] Verify Preorder Sequence in Binary Search Tree 验证二叉搜索树的先序序列

    Given an array of numbers, verify whether it is the correct preorder traversal sequence of a binary ...

  9. [LeetCode98]98. Validate Binary Search Tree判断二叉搜索树

    判断二叉搜索树的方法是: 中序遍历形成递增序列 //全局变量记录中序遍历产生的序列,因为要递归,所以要用全局变量 List<Integer> list = new ArrayList< ...

  10. [leetcode]108. Convert Sorted Array to Binary Search Tree构建二叉搜索树

    构建二叉搜索树 /* 利用二叉搜索树的特点:根节点是中间的数 每次找到中间数,左右子树递归子数组 */ public TreeNode sortedArrayToBST(int[] nums) { r ...

随机推荐

  1. [golang note] 包和导入

    package的作用        √ package是golang最基本的分发单位和工程管理中依赖关系的体现.        √ 每个golang源代码文件开头都拥有一个package声明,表示该g ...

  2. map::erase陷阱

    map::erase函数在不同版本stl中的差异 1. C++98和C++11标准 http://www.cplusplus.com/reference/map/map/erase/ 2. pj st ...

  3. linux rm指定的文件

    如何删除一个目录下的除了想要的文件之外的所有文件 rm `ls | grep -v "aa"` Linux下 报错“命令参数列表过长”,在用mv命令一次移动3万多个文件时失败了,原 ...

  4. AngularJS 笔记系列(四)控制器和表达式

    控制器:在 Angular 中控制器是一个函数,用来向作用域中添加额外的功能.我们用它来给作用域对象设置初始状态,并添加自定义行为. 使用方法: var app = angualr.module('a ...

  5. 我与前端之间不得不说的三天两夜之jQuery

    前端基础之jquery 一 jQuery是什么? [1] jQuery由美国人John Resig创建,至今已吸引了来自世界各地的众多 javascript高手加入其team. [2] jQuery是 ...

  6. centos7使用中文输入法

    centos7自带中文输入法,可能我们在安装时会跳过选择汉语拼音,我们来重新设置一下吧 假如你在命令行界面,输入Ctrl+Alt+F1进入图形界面 点击左上角系统工具   --> 设置 --&g ...

  7. hibernate的事务和spring事务的区别 (转)

    spring事务: 对于传统的基于特定事务资源的事务处理而言(如基于JDBC的数据库访问),Spring并不会对其产生什么影响,我们照样可以成功编写并运行这样的代码.同时,Spring还提供了一些辅助 ...

  8. selenium+python学习总结

    学习了一个月的selenium+python,终于学有所成,下面以一个简单的项目来总结学习所得. 1.         项目结构 在项目结构中,大家要注意到:每一个源文件夹中都要有一个__init__ ...

  9. idea中 在接口中如何直接跳转到该接口的是实现类中?

    例如,我想跳转到UserInfoDao 这个接口的实现类中,操作如下: 把鼠标放到这个接口UserInfoDao 上面,右键,选择 GO To ,然后选择 Implementations,就可以直接跳 ...

  10. Python爬虫学习笔记之爬虫基础库

    知识预览 beautifulsoup的简单使用 beautifulsoup的遍历文档树 beautifulsoup的搜索文档树 beautifulsoup的css选择器 回到顶部 beautifuls ...