zoukankan      html  css  js  c++  java
  • LeetCode第[98]题(Java):Validate Binary Search Tree(验证二叉搜索树)

    题目:验证二叉搜索树

    难度: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、然后返回左右节点的递归结果的 “与” (全都符合才算符合)

    我的代码

     1     public boolean isValidBST(TreeNode root) {
     2         if (root == null) {
     3             return true;
     4         }
     5         
     6         if (root.left != null) {
     7             TreeNode cur = root.left;
     8             while (cur.right != null) {
     9                 cur = cur.right;
    10             }
    11             if (cur.val >= root.val) {
    12                 return false;
    13             }
    14         }
    15         
    16         if (root.right != null) {
    17             TreeNode cur = root.right;
    18             while (cur.left != null) {
    19                 cur = cur.left;
    20             }
    21             if (cur.val <= root.val) {
    22                 return false;
    23             }
    24         }
    25         
    26         return isValidBST(root.left) && isValidBST(root.right);
    27     }

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

    编码过程中的问题

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

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

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

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

    答案代码

    1     public boolean isValidBST(TreeNode root) {
    2         return isValidBST(root, Long.MIN_VALUE, Long.MAX_VALUE);
    3     }
    4     
    5     public boolean isValidBST(TreeNode root, long minVal, long maxVal) {
    6         if (root == null) return true;
    7         if (root.val >= maxVal || root.val <= minVal) return false;
    8         return isValidBST(root.left, minVal, root.val) && isValidBST(root.right, root.val, maxVal);
    9     }

    答案复杂度:O(N)

    答案思路

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

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

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

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

    例如:

       5
       / 
      1   6
         / 
        3   7    
    5的满足小于最大值,大于最小值,然后递归(1,MIN,5) && 递归(4,5,MAX)
    。。。
    3节点的最大值为6,最小值应该为5,此时不满足,所以return false

    其实还有一种非递归的解法:中序遍历,利用二叉搜索树中序遍历的有序性(在中序遍历的出栈时判断此值是否小于之前出栈的那个节点的值
     1 public boolean isValidBST(TreeNode root) {
     2    if (root == null) return true;
     3    Stack<TreeNode> stack = new Stack<>();
     4    TreeNode pre = null;
     5    while (root != null || !stack.isEmpty()) {
     6       while (root != null) {
     7          stack.push(root);
     8          root = root.left;
     9       }
    10       root = stack.pop();
    11       if(pre != null && root.val <= pre.val) return false;
    12       pre = root;
    13       root = root.right;
    14    }
    15    return true;
    16 }

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

     
  • 相关阅读:
    [蓝桥杯][基础训练]报时助手
    [蓝桥杯][基础训练]分解质因数
    [蓝桥杯][基础训练]2n皇后问题
    [啊哈算法]我要做月老
    [啊哈算法]关键道路(图的割边)
    [啊哈算法]重要城市(图的割点)
    并查集
    栈数组与栈链表代码实现

    循环链表
  • 原文地址:https://www.cnblogs.com/Xieyang-blog/p/9111962.html
Copyright © 2011-2022 走看看