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, 继而, 看一下, 根节点的值是否大于左子树的最大值并且小于右子树的最小值即可。
这个code 中使用了 upper 和 bott 来限定当前节点的取值范围,因为, 我们的上级节点会对他的子树的取值有限制, ie, 左子树的最大值不能大于该节点的值, 右子树的最小值也必须大于该节点的值。
class Solution {
public:
bool isValidBST(TreeNode* root) {
return isValidBST(root, LLONG_MAX, LLONG_MIN);
}
private:
bool isValidBST(TreeNode * root, long long upper, long long bott){
if (!root) return true;
bool ret = (bott < root->val && upper > root->val);
if (root->left)
ret = (ret && root->left->val < root->val);
if (root->right)
ret = (ret && root->right->val > root->val);
return ret && isValidBST(root->left, root->val, bott) && isValidBST(root->right, upper, root->val);
}
};
这个思路, 是让每个子树都返回他的最大最小值, 不过这个在处理中需要注意空子树的情况, 还是有些费劲的
class Solution {
public:
pair<int, int> findMaxMinTree(TreeNode * root){
int left_min = root->val;
int right_max = root->val;
if (root->left)
left_min = findMaxMinTree(root->left).first;
if (root->right)
right_max = findMaxMinTree(root->right).second;
return pair<int, int>(left_min, right_max);
}
bool isValidBST(TreeNode* root) {
if (root == nullptr)
return true;
pair<int, int> left, right;
if (root->left)
left = findMaxMinTree(root->left);
if (root->right)
right = findMaxMinTree(root->right);
if (root->left && root->right){
if (left.second >= root->val || right.first <= root->val)
return false;
}
else if (root->left){
if (left.second >= root->val)
return false;
}
else if (root->right){
if (right.first <= root->val)
return false;
}
else
return true;
return isValidBST(root->left) && isValidBST(root->right);
}
};
使用prev 标记前一个遍历过的节点, 如果这个节点的值大于当前值, 就必然不是一颗 BST 树了。brilliant!!!
class Solution {
public:
bool isValidBST(TreeNode* root) {
TreeNode* prev = NULL;
return validate(root, prev);
}
bool validate(TreeNode* node, TreeNode* &prev) {
if (node == NULL) return true;
if (!validate(node->left, prev)) return false;
if (prev != NULL && prev->val >= node->val) return false;
prev = node;
return validate(node->right, prev);
}
};
/* Update: If we use in-order traversal to serialize a binary search tree, we can get a list of values in ascending order. It can be proved with the definition of BST. And here I use the reference of TreeNode pointer prev as a global variable to mark the address of previous node in the list. “In-order Traversal”: https://en.wikipedia.org/wiki/Tree_traversal#In-order */
感觉这个思路和我们的思路是一样的。
public 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);
}
}
bool isValidBST(TreeNode* root) {
return isValidBST(root, NULL, NULL);
}
bool isValidBST(TreeNode* root, TreeNode* minNode, TreeNode* maxNode) {
if(!root) return true;
if(minNode && root->val <= minNode->val || maxNode && root->val >= maxNode->val)
return false;
return isValidBST(root->left, minNode, root) && isValidBST(root->right, root, maxNode);
}