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.
method 1 recusive
一开始将本题想的略简单,没有考虑根节点和根节点左孩子的右孩子之间的大小关系 以及 根节点和根节点右孩子的左孩子之间的大小关系,所以做错,为了确保每个结点都符合大小关系,在递归时,加上一个结点需要满足的上下界
- 左孩子的左孩子,必然最小
- 左孩子的右孩子,必然上界为父结点的父结点,下界为父结点
- 右孩子的右孩子,必然最大
- 右孩子的左孩子,必然下界为父结点的父结点,上界为父结点
class Solution {
public:
bool helper(TreeNode* root, long lower, long upper){
if(!root) return true;
if(lower != LONG_MIN && root->val <= lower) return false;
if(upper != LONG_MAX && root->val >= upper) return false;
if(!helper(root->left, lower, root->val)) return false;
if(!helper(root->right, root->val, upper)) return false;
return true;
}
bool isValidBST(TreeNode* root) {
if(!root) return true;
return helper(root, LONG_MIN, LONG_MAX);
}
};
method 2 中序遍历
一颗二叉树的中序遍历得到的序列必然是一个上升的序列,因此可以通过检查序列来检查二叉树是否合法
class Solution {
public boolean isValidBST(TreeNode root) {
Stack<TreeNode> stack = new Stack();
double inorder = - Double.MAX_VALUE;
while (!stack.isEmpty() || root != null) {
while (root != null) {
stack.push(root);
root = root.left;
}
root = stack.pop();
// If next element in inorder traversal
// is smaller than the previous one
// that's not BST.
if (root.val <= inorder) return false;
inorder = root.val;
root = root.right;
}
return true;
}
}
summary
- 考虑大小关系时,不能简单考虑邻近两层的关系,grandparent 结点的大小关系也要考虑,因此设立上下界,并随着遍历,更新上下界
- 处理树的问题,可以归结为树的遍历顺序问题,并检查遍历结果来解决