「这是我参与11月更文挑战的第19天,活动详情查看:2021最后一次更文挑战」
98. 验证二叉搜索树
题目描述
给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。
有效 二叉搜索树定义如下:
- 节点的左子树只包含 小于 当前节点的数。
- 节点的右子树只包含 大于 当前节点的数。
- 所有左子树和右子树自身必须也是二叉搜索树。
示例 1:
输入: root = [2,1,3]
输出: true
示例 2:
输入: root = [5,1,4,null,null,3,6]
输出: false
解释: 根节点的值是 5 ,但是右子节点的值是 4 。
解析
使用中序遍历,将节点的值存入到数组中。再判断数组是否是递增的(且不含重复元素),递增则说明是二叉搜索树,否则就不是。
- 二叉树的特点:
- 左子树的节点值都小于当前节点值
- 右子树的节点值都大于当前节点值
递归法
// 中序遍历
// 使用数组存储节点的值,如果节点的值是有序递增的,则说明是二叉搜索树
class Solution
{
public:
bool isValidBST(TreeNode *root)
{
vec.clear();
traversal(root);
// 二叉搜索树中没有重复的节点
for (int i = 1; i < vec.size(); i++)
{
if (vec[i] <= vec[i - 1])
{
return false;
}
}
return true;
}
private:
vector<int> vec;
// 将二叉搜索树的节点存入到数组中
void traversal(TreeNode *node)
{
if (node == NULL)
{
return;
}
// 左
traversal(node->left);
// 中
vec.push_back(node->val);
// 右
traversal(node->right);
}
};
迭代法
class Solution
{
public:
bool isValidBST(TreeNode *root)
{
if (root == NULL)
{
return false;
}
// 中序遍历存放节点
stack<TreeNode *> st;
// 当前遍历的节点
TreeNode *cur = root;
// 记录前一个节点
TreeNode *pre = NULL;
while (cur != NULL || !st.empty())
{
if (cur != NULL)
{
st.push(cur);
// 左
cur = cur->left;
}
else
{
cur = st.top();
st.pop();
if (pre != NULL && cur->val <= pre->val)
{
return false;
}
// 保存前一个访问的节点
pre = cur;
// 右
cur = cur->right;
}
}
return true;
}
};