98. Validate Binary Search Tree

Bloomberg recruiter 在 career fair上问的一道题,当时太着急没想到全部的case,在recruiter的提醒下终于想清楚了——除了要满足 leftChild.val < parent.val < rightChild.val 之外,还要注意当前子树中的所有节点都要满足ceiling和floor的约束。

其实为什么Sedgewick的算法书里面在BST部分要引入ceiling() 和 floor() 这两个API,原因是对于一个合法的Binary Search Tree,其中每一个节点,都要满足小于ceiling大于floor,而一个节点的ceiling和floor是由其祖先节点决定的。具体而言如下:

如果一个节点是其parent的leftChild,则该节点的ceiling是其parent的value值,而该节点的floor则继承其parent节点的floor;
如果一个节点是其parent的rightChild,则该节点的ceiling继承自其parent的ceiling,而该节点的floor则为其parent的value值。

因此不仅仅是需要将parent的值传入,而是要传入 或者 以这种的限制来自上而下验证所有的节点是否合法,所有节点合法则该BST合法。

*初始的root节点的值是任意的(废话),也就意味着 ceiling 和 floor是[-∞, +∞],程序中可表示的整型最大值(4 bytes)为 2^31-1, Java 中整型最大值最小值分别为 Integer.MAX_VALUE 与 Integer.MIN_VALUE.

代码如下:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution 
{
    public boolean isValidBST(TreeNode root) 
    {
            long ceiling = (long) Integer.MAX_VALUE + 1;
            long floor = (long) Integer.MIN_VALUE - 1;
            return isValidBSTHelper(root, ceiling, floor);
    }
    public boolean isValidBSTHelper(TreeNode node, long ceiling, long floor)
    {
        if(node == null)
            return true;
        else if(node.val >= ceiling || node.val <= floor)
            return false;
        else
        {
            boolean isValidLeft = isValidBSTHelper(node.left, node.val, floor);
            boolean isValidRight = isValidBSTHelper(node.right, ceiling, node.val);
            return isValidLeft && isValidRight;
        }
    }
}

需要注意的是其中初始的root节点的 ceiling 和 floor 值设置问题。某一次提交后发现test case [2147483647] 不通过,2147483647 = 2^31 -1,也就是说这个case是专门用来考察初始ceiling和floor的设置的。由于 BST 被当做一种 Symbol Table(含有 key-value 结构),key 值默认是不相等的,所以通常来说 BST 中左根右的大小关系是严格的小于而非小于等于。如果初始 root 节点的 ceiling 值设为2^31-1 = 2147483647 则会误判为非法。

解决办法为:将 Integer.MAX_VALUE 和 Integer.MIN_VALUE cast 为 long 类型后,分别 +1 和 -1,以此作为 root 节点的初始 ceiling 和 floor 值。如果不转换为 long,则 +1 和 -1 后会溢出,所得的值无法作为 ceiling 和 floor。

你可能感兴趣的:(98. Validate Binary Search Tree)