【Leetcode】Validate Binary Search Tree

来源:互联网 发布:软件激活码商城 编辑:程序博客网 时间:2024/05/29 11:36

题目:

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.

Example 1:

    2   / \  1   3
Binary tree [2,1,3], return true.

Example 2:

    1   / \  2   3
Binary tree [1,2,3], return false.

分析:

这题的解法很多种,可以利用它本身的性质来做,即左<根<右,也可以通过利用中序遍历结果为有序数列来做,下面我们先来看最简单的一种,就是利用其本身性质来做,初始化时带入系统最大值和最小值,在递归过程中换成它们自己的节点值,用long代替int就是为了包括int的边界条件,代码如下:

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 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);    }}

C++版本:

/** * Definition for a binary tree node. * struct TreeNode { *     int val; *     TreeNode *left; *     TreeNode *right; *     TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */// Recursion without inorder traversalclass Solution {public:    bool isValidBST(TreeNode *root) {        return isValidBST(root, LONG_MIN, LONG_MAX);    }    bool isValidBST(TreeNode *root, long mn, long mx) {        if (!root) return true;        if (root->val <= mn || root->val >= mx) return false;        return isValidBST(root->left, mn, root->val) && isValidBST(root->right, root->val, mx);    }};

Python版本:

# Definition for a binary tree node.# class TreeNode:#     def __init__(self, x):#         self.val = x#         self.left = None#         self.right = Noneclass Solution(object):    def isValidBST(self, root, lessThan = float('inf'), largerThan = float('-inf')):        if not root:            return True        if root.val <= largerThan or root.val >= lessThan:            return False        return self.isValidBST(root.left, min(lessThan, root.val), largerThan) and \               self.isValidBST(root.right, lessThan, max(root.val, largerThan))


中序遍历法:

这题实际上简化了难度,因为一般的二叉搜索树是左<=根<右,而这道题设定为左<根<右,那么就可以用中序遍历来做。因为如果不去掉左=根这个条件的话,那么下边两个数用中序遍历无法区分:

   20       20
   /           \
 20           20

它们的中序遍历结果都一样,但是左边的是BST,右边的不是BST。去掉等号的条件则相当于去掉了这种限制条件。下面我们来看使用中序遍历来做,这种方法思路很直接,通过中序遍历将所有的节点值存到一个数组里,然后再来判断这个数组是不是有序的,代码如下:

Java版本:

public class Solution {    public boolean isValidBST(TreeNode root) {        List<Integer> list = new ArrayList<Integer>();        inorder(root, list);        for (int i = 0; i < list.size() - 1; ++i) {            if (list.get(i) >= list.get(i + 1)) return false;        }        return true;    }    public void inorder(TreeNode node, List<Integer> list) {        if (node == null) return;        inorder(node.left, list);        list.add(node.val);        inorder(node.right, list);    }}
C++版本:

// Recursionclass Solution {public:    bool isValidBST(TreeNode *root) {        if (!root) return true;        vector<int> vals;        inorder(root, vals);        for (int i = 0; i < vals.size() - 1; ++i) {            if (vals[i] >= vals[i + 1]) return false;        }        return true;    }    void inorder(TreeNode *root, vector<int> &vals) {        if (!root) return;        inorder(root->left, vals);        vals.push_back(root->val);        inorder(root->right, vals);    }};