- Validate Binary Search Tree
中文English
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.
A single node tree is a BST
Example
Example 1:
Input: For the following binary tree(only one node):
-1
Output:true
Example 2:
Input: For the following binary tree:
2
/ \
1 4
/ \
3 5
Output: true
这题有两种解法:
解法1:利用binary search tree <=> 中序遍历为升序序列 这个充要条件。
注意这题条件好像认为bst不存在重复元素,但实际上是可以重复的,而且重复元素(根和子节点值一样的话),子节点放在左边。
代码如下:
/**
* Definition of TreeNode:
* class TreeNode {
* public:
* int val;
* TreeNode *left, *right;
* TreeNode(int val) {
* this->val = val;
* this->left = this->right = NULL;
* }
* }
*/
class Solution {
public:
/**
* @param root: The root of binary tree.
* @return: True if the binary tree is BST, or false
*/
TreeNode *lastNode;
bool isValid;
bool isValidBST(TreeNode * root) {
lastNode=NULL;
isValid=true;
inorderTraversal(root);
return isValid;
}
void inorderTraversal(TreeNode *root) {
if (!root) return;
inorderTraversal(root->left);
if (lastNode && root->val <= lastNode->val) {
isValid=false;
return;
} else {
lastNode=root;
}
inorderTraversal(root->right);
}
};
代码2: 分治法。左右两边分别递归。下次再写。
/**
* Definition of TreeNode:
* class TreeNode {
* public:
* int val;
* TreeNode *left, *right;
* TreeNode(int val) {
* this->val = val;
* this->left = this->right = NULL;
* }
* }
*/
struct ResultType {
bool isBST;
TreeNode * minNode, * maxNode;
ResultType(bool is_bst = true, TreeNode * min_node = NULL, TreeNode * max_node = NULL) : isBST(is_bst), minNode(min_node), maxNode(max_node) {}
};
class Solution {
public:
/**
* @param root: The root of binary tree.
* @return: True if the binary tree is BST, or false
*/
bool isValidBST(TreeNode * root) {
//if (!root) return true;
//if (!root->left && !root->right) return true;
return helper(root).isBST;
}
private:
ResultType helper(TreeNode * root) {
if (!root) return ResultType(true);
if (!root->left && !root->right) return ResultType(true, root, root);
ResultType left = helper(root->left);
if (!left.isBST) return ResultType(false);
ResultType right = helper(root->right);
if (!right.isBST) return ResultType(false);
//now both left and right subtree are BST
if (left.maxNode && root->val <= left.maxNode->val) return ResultType(false);
if (right.minNode && root->val >= right.minNode->val) return ResultType(false);
//the tree is already BST, now need to set the minNode and maxNode
//return ResultType(true, left.minNode, right.maxNode);
ResultType result = ResultType(true);
result.minNode = left.minNode ? left.minNode : root;
result.maxNode = right.maxNode ? right.maxNode : root;
return result;
}
};
注意:
- 最后返回时应该考虑left.minNode和right.maxNode是否存在,若否,则用root代替。
- 下面这一行并不需要。
if (!root->left && !root->right) return ResultType(true, root, root);
3)下面这种写法不对。因为没有考虑所有左子树节点的最大值和所有右子树节点的最小值。
bool isValidBST(TreeNode * root) {
if (!root) return true;
if (!root->left && !root->right) return true;
if (root->left && root->left->val >= root->val) return false;
if (root->right && root->right->val <= root->val) return false;
if (isValidBST(root->left) && isValidBST(root->right)) return true;
return false;
}
另外总结一个小知识点:
二叉树的分治法是否需要用到Memorization呢?答案是不需要,因为Memorization和分治法的区别是看有没有重复搜索。二叉树在左子树和右子树没有重复。