📜  检查有效的二叉搜索树 java - C# (1)

📅  最后修改于: 2023-12-03 14:55:49.199000             🧑  作者: Mango

检查有效的二叉搜索树

在Java和C#中,检查二叉树是否为有效的二叉搜索树是一项常见的任务。一个有效的二叉搜索树(BST)必须满足以下条件:

  • 每个节点都有一个唯一的键。
  • 左子树的所有节点的键值小于父节点的键值。
  • 右子树的所有节点的键值大于父节点的键值。
  • 左右子树本身也必须是有效的二叉搜索树。
方法一:递归法

在递归法中,我们使用一个辅助函数isValidBSTHelper(),它采用四个参数:

  • root - 当前子树的根节点
  • minValue - 子树中允许存在的最小值
  • maxValue - 子树中允许存在的最大值
  • isLeft - 指示当前子树是左子树还是右子树

在该函数内部,我们首先检查当前节点是否为空。如果为空,我们返回true。如果节点不为空,我们检查它的键值是否在其允许范围内。如果键值超出允许范围,我们返回false。否则,我们递归地检查其左子树和右子树。如果任何一棵子树不符合要求,我们返回false。最后,如果所有子树均为有效的二叉搜索树,我们返回true。

Java代码:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public boolean isValidBST(TreeNode root) {
        return isValidBSTHelper(root, Long.MIN_VALUE, Long.MAX_VALUE, true);
    }
    
    private boolean isValidBSTHelper(TreeNode root, long minValue, long maxValue, boolean isLeft) {
        if (root == null) {
            return true;
        }
        
        if (root.val <= minValue || root.val >= maxValue) {
            return false;
        }
        
        boolean leftValid = true;
        boolean rightValid = true;
        
        if (root.left != null) {
            leftValid = isValidBSTHelper(root.left, minValue, root.val, true);
        }
        
        if (root.right != null) {
            rightValid = isValidBSTHelper(root.right, root.val, maxValue, false);
        }
        
        return leftValid && rightValid;
    }
}

C#代码:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     public int val;
 *     public TreeNode left;
 *     public TreeNode right;
 *     public TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    public bool IsValidBST(TreeNode root) {
        return IsValidBSTHelper(root, long.MinValue, long.MaxValue, true);
    }
    
    private bool IsValidBSTHelper(TreeNode root, long minValue, long maxValue, bool isLeft) {
        if (root == null) {
            return true;
        }
        
        if (root.val <= minValue || root.val >= maxValue) {
            return false;
        }
        
        bool leftValid = true;
        bool rightValid = true;
        
        if (root.left != null) {
            leftValid = IsValidBSTHelper(root.left, minValue, root.val, true);
        }
        
        if (root.right != null) {
            rightValid = IsValidBSTHelper(root.right, root.val, maxValue, false);
        }
        
        return leftValid && rightValid;
    }
}
方法二:中序遍历法

在中序遍历法中,我们首先对二叉树进行中序遍历,并记录每个节点的键值。由于二叉搜索树的中序遍历结果是一个递增的序列,我们只需要检查该序列是否递增即可。

Java代码:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    private long prevValue = Long.MIN_VALUE;
    
    public boolean isValidBST(TreeNode root) {
        if (root == null) {
            return true;
        }
        
        if (!isValidBST(root.left)) {
            return false;
        }
        
        if (root.val <= prevValue) {
            return false;
        }
        
        prevValue = root.val;
        
        if (!isValidBST(root.right)) {
            return false;
        }
        
        return true;
    }
}

C#代码:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     public int val;
 *     public TreeNode left;
 *     public TreeNode right;
 *     public TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    private long prevValue = long.MinValue;
    
    public bool IsValidBST(TreeNode root) {
        if (root == null) {
            return true;
        }
        
        if (!IsValidBST(root.left)) {
            return false;
        }
        
        if (root.val <= prevValue) {
            return false;
        }
        
        prevValue = root.val;
        
        if (!IsValidBST(root.right)) {
            return false;
        }
        
        return true;
    }
}

无论是递归法还是中序遍历法都可以有效地检查二叉树是否为有效的二叉搜索树。需要注意的是,在Java和C#中,整型的最小值和最大值可能与 long 类型的最小值和最大值不同,因此我们应该始终使用 long 类型的最小值和最大值进行比较。