Title:
Given a binary tree, determine if it is a valid binary search tree (BST).
Assume a BST is defined as follows:
(1) The left subtree of a node contains only nodes with keys less than the node's key.
(2) The right subtree of a node contains only nodes with keys greater than the node's key.
(3) Both the left and right subtrees must also be binary search trees.
思路:(1)第一下就是使用递归比较一个节点是否比左子节点大,比右子节点小。但是一想这是有问题的,如
5
/
4 10
/
3 11
这样的树是符合我所想的递归,但是不符合二叉搜索树的要求。
但是网上有人根据这个类似的想法,也是使用递归。与前面错误的递归相反,这个递归想法是对每个节点,看是否符合当前传递的左右值,而不是看其左右子节点。网上很用人用了INT_MAX和INT_MIN来辅助解决这道题,即遍历时记录一个当前允许的最大值和最小值。但是并不能通过测试,因为LeetCode新增了测试用例
Input: | {-2147483648,#,2147483647} |
Output: | false |
Expected: | true |
/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class Solution { public: bool isValidBST(TreeNode* root) { return check(root,INT_MIN,INT_MAX); } bool check(TreeNode* p , int leftValue, int rightValue){ if(p == NULL) return true; return (p->val > leftValue && p->val < rightValue) && check(p->left,leftValue,p->val) && check(p->right,p->val,rightValue); } };
(2)使用中序遍历,因此BST必须符合中序遍历是递增的
/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class Solution { public: bool isValidBST(TreeNode* root) { vector<int> v; midOrder(v,root); for (int i = 1 ; i < v.size(); i++){ if (v[i] <= v[i-1]) return false; } return true; } void midOrder(vector<int> & v, TreeNode* root){ stack<TreeNode*> s; TreeNode* p = root; while (p || !s.empty()){ while (p){ s.push(p); p = p->left; } if (!s.empty()){ p = s.top(); v.push_back(p->val); p = p->right; s.pop(); } } } };
网上一个更好的,不需要额外O(n)空间的代码
class Solution { // Keep the previous value in inorder traversal. public: TreeNode* pre = NULL; bool isValidBST(TreeNode* root) { // Traverse the tree in inorder. if (root != NULL) { // Inorder traversal: left first. if (!isValidBST(root->left)) return false; // Compare it with the previous value in inorder traversal. if (pre != NULL && root->val <= pre->val) return false; // Update the previous value. pre = root; // Inorder traversal: right last. return isValidBST(root->right); } return true; } };