题目:验证二叉搜索树

难度: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. mysql 约束条件 auto_increment 自动增长

    约束字段为自动增长,被约束的字段必须同时被key约束 id自动增长,每插入一条记录,自动增长 创建一张表 t20 id 字段设置为 不为空 唯一 自动增长 mysql)); Query OK, row ...

  2. XSS注入学习

    引贴: http://mp.weixin.qq.com/s?__biz=MzIyMDEzMTA2MQ==&mid=2651148212&idx=1&sn=cd4dfda0b92 ...

  3. php的soap无故出错的真凶:wsdl缓存

    soap不更新的真凶: 当我修改了服务端的调用方法后,更新了wsdl,客户端的参数老是丢失(不是全丢失,而是部分),让人很郁闷. 第二天我索性增加了一个服务端的新方法,更新了wsdl,但是客户端请求却 ...

  4. 微信公众号JSAPI支付

    微信公众号JSAPI支付 一:配置参数 申请成功后,获取接口文件, 将所有文件放入项目根目录weixin下,在WxPay.ub.config.php中填入配置账户信息; 二:设置授权 开发者中心-&g ...

  5. ajax示例

    ajax(Asynchronous Javascript And XML)翻译成中文就是异步的javascript和XML,即用javascript语言与服务器进行异步交互,传输的数据为XML(当然, ...

  6. java 定时器实现

    java工程中,不免遇到需要定时处理任务的需求,有如下两种方法: 1.使用java.util.TimerTask 2.使用Quartz 一.java.util.TimerTask Timer time ...

  7. Git在Githib和Github上的使用

    本文使用的环境是linux里 一.git的常用命令解释: 1.基础命令: git init #创建版本库 git add <file> #将文件修改添加到暂存区 git commit -m ...

  8. 2016-2017 National Taiwan University World Final Team Selection Contest C - Crazy Dreamoon

    题目:Statements Dreamoon likes algorithm competitions very much. But when he feels crazy because he ca ...

  9. XVII Open Cup named after E.V. Pankratiev Grand Prix of Moscow Workshops, Sunday, April 23, 2017 Problem K. Piecemaking

    题目:Problem K. PiecemakingInput file: standard inputOutput file: standard outputTime limit: 1 secondM ...

  10. JS正则表达式从入门到入土(1)—— REGEXP对象

    REGEXP对象 JavaScript通过内置对象RegExp支持正则表达式,有两种方法实例化RegExp对象. 1.字面量 2.构造函数 字面量 字面量是直接通过/.../创建RegExp对象实例. ...