98. Validate Binary Search Tree(验证是否为二叉树搜索树)

题目描述

给定一个二叉树,判断其是否是一个有效的二叉搜索树。

假设一个二叉搜索树具有如下特征:
节点的左子树只包含小于当前节点的数。
节点的右子树只包含大于当前节点的数。
所有左子树和右子树自身必须也是二叉搜索树。
在这里插入图片描述

方法思路

Approach1: recursive + inorder traversal
Compute inorder traversal list inorder.
Check if each element in inorder is smaller than the next one.

class Solution{
    //Runtime: 1 ms, faster than 39.94% 
    //Memory Usage: 38.5 MB, less than 47.99%
    List<Integer> list;
    public boolean isValidBST(TreeNode root) {
        if(root == null) return true;
        list = new ArrayList<>();
        validHelper(root);
        for(int i = 0; i < list.size() - 1; i++)
            if(list.get(i) >= list.get(i + 1))
                return false;
        return true;
    }
    
    public void validHelper(TreeNode root){
        if(root == null) return;
        validHelper(root.left);
        list.add(root.val);
        validHelper(root.right);
        return;
    }
}

Approach2: 方法一的非递归实现

Do we need to keep the whole inorder traversal list?

Actually, no. The last added inorder element is enough to ensure at each step that the tree is BST (or not). Hence one could merge both steps into one and reduce the used space.

class Solution {
    //Memory Usage: 40.3 MB, less than 5.22%
    //Runtime: 2 ms, faster than 24.92% 
  public boolean isValidBST(TreeNode root) {
    Stack<TreeNode> stack = new Stack();
    double inorder = - Double.MAX_VALUE;

    while (!stack.isEmpty() || root != null) {
      while (root != null) {
        stack.push(root);
        root = root.left;
      }
      root = stack.pop();
      // If next element in inorder traversal
      // is smaller than the previous one
      // that's not BST.
      if (root.val <= inorder) return false;
      inorder = root.val;
      root = root.right;
    }
    return true;
  }
}

Approach3: recursive (觉得是很乱的方法却又是效率最高的)tricky
The idea above could be implemented as a recursion. One compares the node value with its upper and lower limits if they are available. Then one repeats the same step recursively for left and right subtrees.

class Solution {
    //Runtime: 0 ms, faster than 100.00% 
    //Memory Usage: 38.2 MB, less than 71.81%
  public boolean isBSTHelper
      (TreeNode node, Integer lower_limit, Integer upper_limit) {
    
      if ((lower_limit != null) && (node.val <= lower_limit))
        return false;
      if ((upper_limit != null) && (upper_limit <= node.val))
        return false;

    boolean left = 
        node.left != null ? isBSTHelper(node.left, lower_limit, node.val) : true;
    if (left) {
      boolean right = 
        node.right != null ? isBSTHelper(node.right, node.val, upper_limit) : true;
      return right;
    } else
      return false;
  }

  public boolean isValidBST(TreeNode root) {
    if (root == null)
      return true;

    return isBSTHelper(root, null, null);
  }
}

Approach4:方法三的非递归实现
The above recursion could be converted into iteration, with the help of stack. DFS would be better than BFS since it works faster here.

class Solution {
    //Runtime: 2 ms, faster than 24.92% 
    //Memory Usage: 40.4 MB, less than 5.01%
  public boolean isValidBST(TreeNode root) {
    if (root == null)
      return true;

    LinkedList<TreeNode> stack = new LinkedList();
    LinkedList<Integer> upper_limits = new LinkedList();
    LinkedList<Integer> lower_limits = new LinkedList();
    stack.add(root);
    upper_limits.add(null);
    lower_limits.add(null);

    while (!stack.isEmpty()) {
      TreeNode node = stack.poll();
      Integer lower_limit = lower_limits.poll();
      Integer upper_limit = upper_limits.poll();
      if (node.right != null) {
        if (node.right.val > node.val) {
          if ((upper_limit != null) && (node.right.val >= upper_limit))
            return false;
          stack.add(node.right);
          lower_limits.add(node.val);
          upper_limits.add(upper_limit);
        } else
          return false;
      }

      if (node.left != null) {
        if (node.left.val < node.val) {
          if ((lower_limit != null) && (node.left.val <= lower_limit))
            return false;
          stack.add(node.left);
          lower_limits.add(lower_limit);
          upper_limits.add(node.val);
        } else
          return false;
      }
    }
    return true;
  }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值