题目如下:
分析如下:
这道题目如果不用递归,可以利用一个特点来做判断,就是中序遍历树的时候,得到的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); } };
如这样的测试例子:
{-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); } };