LeetCode 98. Validate Binary Search Tree
来源:互联网 发布:淘宝没发货退款 信誉 编辑:程序博客网 时间:2024/05/16 02:23
LeetCode 98. Validate Binary Search Tree
题目很短,大概讲的是要求是判断输入是否是一个BST。其中BST的定义如下:
- 左子树的所有结点都比根小
- 右子树的所有结点都比根大
- 所有左子树和右子树都是BST
题目的第一个坑是,题目并没有把BST的全部定义写全了,漏了下面这个:
- 没有相同值的结点
为了不给大家提示,题目里的例题给的是前序遍历的排序。其实很容易想到只需要做一次中序遍历,然后检查遍历的队列是否是单调递增的就可以了。
中序遍历方法
static list<int> serializeBST;class Solution {public: bool isValidBST(TreeNode* root) { if(root == NULL) return true; serializeBST.clear(); printBST(root); list<int>::const_iterator i = serializeBST.begin(); i++; list<int>::const_iterator j = serializeBST.begin(); for(;i != serializeBST.end(); i++,j++) { if(*j >= *i) return false; } return true; } void printBST(TreeNode* root) { if(root != NULL) { printBST(root->left); serializeBST.push_back(root->val); printBST(root->right); } return; }};
二叉树的遍历的递归中,每个结点都需要遍历一次,时间复杂度是O(n),每次list的push_back操作时间复杂度是O(1),最后遍历一次队列时间复杂度是O(n)。所以总的时间复杂度是O(n)+O(n)。而最差情况是严重不平衡的二叉搜索树,递归调用深度是O(n),空间复杂度是O(n)。而list的空间复杂度也是O*(n),所以总的空间复杂度是O(n)。
- 答主用了static关键字,用来在static区上创建一个数组,事实上这样会减低代码的runtime,推荐写进class做为一个private的变量,这样结果一样,也不会那么慢
然后当然没完,这样写的话,无论什么情况,都必须遍历整个二叉树后才能判断是否是BST,这样太笨了,能不能一旦找到了错误的地方就立刻报false呢?这样最坏情况和上次方法一致,但平均时间复杂度变成了O(log*n)。而通过方法一,很明显我们也发现在比较的步骤里,永远只需要前一位和后一位比较大小,所以只需要存前一位的大小就可以了,这样优化的空间复杂度是*O(1)。
优化的中序遍历
class Solution {private: int g_leftmax = -1; bool first = true;public: bool isValidBST(TreeNode* root) { if(root == NULL) return true; if(!isValidBST(root->left)) return false; if(!first && root->val <= g_leftmax) return false; first = false; g_leftmax = root->val; if(!isValidBST(root->right)) return false; return true; }};
代码更加简洁了,不过这里有几个点要注意的。
- LeetCode最近更新过一次test case,增加了int的边界条件,最小的结点值可以去到INT_MIN,所以如果不用first判断是否第一次的话,很有可能会出现第一个点的值就等于g_leftmax,从而报false。当然,网上有一些是将g_leftmax实现为一个初始值为NULL的TreeNode指针,这样就可以通过判断指针是否为空来判断是否为第一次
这样就快多了,而且空间复杂度也优化了不少。
既然有递归,我们自然可以用栈来做非递归的方法,这样理论上可以降低递归深度很大的时候的函数调用的时间开销。(但结果是栈实现的方法runtime更加大……这就神奇了。)
用栈实现的非递归方法
class Solution {public: bool isValidBST(TreeNode* root) { stack<TreeNode*> s; TreeNode *p = root, *pleftmax= NULL; while (p || !s.empty()) { while (p) { s.push(p); p = p->left; } TreeNode *t = s.top(); s.pop(); if (pleftmax&& t->val <= pleftmax->val) return false; pleftmax= t; p = t->right; } return true; }};
拓展
这道题拓展开来,可以有:
- 左子树小于等于根结点,而右子树大于根结点,这样中序历遍就无法解决问题了(10,10到底是左子树是10–合法,还是右子树是10–非法)
- LeetCode 98. Validate Binary Search Tree
- [LeetCode]98.Validate Binary Search Tree
- [Leetcode] 98. Validate Binary Search Tree
- LeetCode --- 98. Validate Binary Search Tree
- [leetcode] 98.Validate Binary Search Tree
- [leetcode] 98.Validate Binary Search Tree
- [Leetcode] 98. Validate Binary Search Tree @python
- Leetcode 98. Validate Binary Search Tree
- [LeetCode]98. Validate Binary Search Tree
- leetcode 98. Validate Binary Search Tree
- *LeetCode 98. Validate Binary Search Tree
- 98. Validate Binary Search Tree LeetCode
- LeetCode 98. Validate Binary Search Tree
- LeetCode 98. Validate Binary Search Tree
- LeetCode *** 98. Validate Binary Search Tree
- 98. Validate Binary Search Tree-leetcode-java
- [leetcode] 98. Validate Binary Search Tree
- LeetCode - 98. Validate Binary Search Tree
- 函数调用堆栈
- BIBTeX制作参考文献 [转]
- 产生冠军 HDU-2094
- Hadoop分布式搭建、Hbase安装、Hive安装
- 设计模式(十五):原型模式
- LeetCode 98. Validate Binary Search Tree
- 【数据结构】海量数据处理题
- C语言实现 poj3666(动态规划)
- 无聊的日
- jieba中文分词应用
- 周易六十四卦——雷山小过卦
- 算法设计与应用基础-第一周题目
- 【C#】泛型基础
- Oracle入门---简单命令