题解 | #判断是不是二叉搜索树#
判断是不是二叉搜索树
http://www.nowcoder.com/practice/a69242b39baf45dea217815c7dedb52b
判断是不是二叉搜索树
题意
给定一个树,判断它是不是二叉搜索树
方法
转化成数组再比较
分析
一个树,是二叉搜索树,则它的中序遍历是递增数组
因此考虑通过先得到它的中序遍历,再判断数组内容是否有序
代码
/**
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* };
*/
class Solution {
public:
void dfs(TreeNode* root, vector<int>& arr){
if(root == NULL)return;
dfs(root->left,arr);
arr.push_back(root->val); // 中序遍历
dfs(root->right,arr);
}
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param root TreeNode类
* @return bool布尔型
*/
bool isValidBST(TreeNode* root) {
vector<int> vals;
dfs(root,vals);
for(int i = 1;i < vals.size();i++){ // 判断是否有序
if(vals[i] < vals[i-1])return false;
}
return true;
}
};
复杂度分析
空间复杂度: 使用了数组来得到中序遍历,空间复杂度为
时间复杂度: 对于每个节点操作代价为常数,所以总时间复杂度为
遍历过程中比较
分析
如果一个树上每个节点和它左右子树相比较都合法,那么整个树合法
而对于一个节点只关心它左树的最大值和右树的最小值
考虑递归过程中,改造成返回一个树的最小值和最大值,而不是产生遍历
这样每个节点去检验,如果都满足则整个树合法
样例
以样例数据为例,
代码
/**
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* };
*/
class Solution {
public:
pair<int,int> dfs(TreeNode* root, bool & r){
if(root == NULL)return {0,0};
pair<int,int> ret = {root->val,root->val}; // 以当前节点为根的树的最小值和最大值
if(root -> left){ // 左节点不为空
auto lr = dfs(root->left,r);
if(!r)return ret; // 失败提前返回
if(lr.second >= root -> val) { // 左树最大值应该小于根节点
r = false;
return ret;
}
ret.first = lr.first; // 更新最小值
}
if(root -> right){ // 右节点不为空
auto lr = dfs(root->right,r);
if(!r)return ret; // 失败提前返回
if(lr.first < root -> val) { // 右树最小值应该大于根节点
r = false;
return ret;
}
ret.second = lr.second; // 更新最大值
}
return ret;
}
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param root TreeNode类
* @return bool布尔型
*/
bool isValidBST(TreeNode* root) {
bool r = true; // 是否合法
dfs(root,r);
return r;
}
};
复杂度分析
空间复杂度: 主要和递归深度相关,最坏情况树是链状,空间复杂度为
时间复杂度: 对于每个节点操作代价为常数,所以总时间复杂度为