题目如下:
分析如下:
这道题目如果不用递归,可以利用一个特点来做判断,就是中序遍历树的时候,得到的node中的值一定是递增的。如果用递归,可以用题目给定的定义做判断。
我的代码
//18ms
class Solution {
public:
bool isValidBST(TreeNode *root) {
std::stack<TreeNode*> stack1;
TreeNode* current = NULL;
TreeNode* pre = NULL;
while (root != NULL) {
stack1.push(root);
root = root->left;
}
while (!stack1.empty()) {
current = stack1.top();
stack1.pop();
if ( pre!= NULL && pre->val >= current->val)
return false;
pre = current; //NOTE: pre = current需在if()之后。这样current更新了,而pre来不及更新,依然保留上一轮循环的值。
current = current->right;
while(current != NULL) {
stack1.push(current);
current = current->left;
}
}
return true;
}
};
小结
(1) 一定要精准要细心,一开始把判断条件
if((pre!=NULL)&&(cur->val<=pre->val))
写成了
if((pre!=NULL)&&(cur->val<pre->val))
就没有通过测试
(2) 看来递归和三种遍历是掌握树类型的题目的基本神器。
update: 2014 - 11 - 28
写了一下递归。发现错了,这个例子没通过。{10,5,15,#,#,6,20}
10
5 15
6 20
想了一下,可以这么改,给每个节点都设定min和max的范围。
代码如下:
下面的代码是个有缺陷的代码。
class Solution {
public:
bool myIsValidBST(TreeNode *root, int min_val, int max_val) {
if (root == NULL) return true;
else if (root->right != NULL && (root->right->val >= max_val || root->right->val <= root->val)) return false;
else if (root->left != NULL && (root->left->val >= root->val || root->left->val <= min_val)) return false;
else return myIsValidBST(root->left, min_val, root->val) && myIsValidBST(root->right, root->val, max_val);
}
bool isValidBST(TreeNode *root) {
return myIsValidBST(root, INT_MIN, INT_MAX);
}
};
这个代码看上去是正确的,但是其实在出现节点value正好等于INT_MIN或者INT_MAX的时候,是不能通过测试的。
如这样的测试例子:
{-2147483648,#,2147483647}
我怀疑是Leetcode更新了自己的测试数据,所以这个代码在老数据上能够测试通过,新数据上却不能。
update: 2015-03-24
能够跑通过的递归的算法是,只需要把参数换成long就可以了,这样可以用INT_MIN - 1和MINT_MAX + 1表示下界和上界(左开右开区间的上界和下界)
// 19ms
class Solution {
public:
bool isValidBST_(TreeNode* root, long start, long end) {
if (root == NULL) {
return true;
}
if (root->val <= start) return false;
if (root->val >= end) return false;
if (root->left != NULL) {
if (root->right != NULL) {
return (root->val > root->left->val) && isValidBST_(root->left, start, root->val)
&& (root->val < root->right->val) && isValidBST_(root->right, root->val, end);
} else {
return (root->val > root->left->val) && isValidBST_(root->left, start, root->val);
}
} else if (root->right != NULL) {
return (root->val < root->right->val) && isValidBST_(root->right, root->val, end);
} else {
return true;
}
}
bool isValidBST(TreeNode *root) {
return isValidBST_(root, (long)INT_MIN -1, (long)INT_MAX + 1);
}
};
后来又看了看,网上一个更简洁的办法是这样的:
class Solution {
public:
bool isValidBST_(TreeNode* root, long start, long end) {
if (root == NULL) {
return true;
}
if (root->val <= start) return false;
if (root->val >= end) return false;
bool leftSubTree = isValidBST_(root->left, start, root->val);
bool rightSubTree = isValidBST_(root->right, root->val, end);
return leftSubTree && rightSubTree;
}
bool isValidBST(TreeNode *root) {
return isValidBST_(root, (long)INT_MIN -1, (long)INT_MAX + 1);
}
};