题目链接:https://leetcode.cn/problems/validate-binary-search-tree/description/
题目叙述:
给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。
有效二叉搜索树定义如下:
- 节点的左子树只包含 小于 当前节点的数。
- 节点的右子树只包含 大于 当前节点的数。
- 所有左子树和右子树自身必须也是二叉搜索树。
示例 1:
输入:root = [2,1,3]
输出:true
示例 2:
输入:root = [5,1,4,null,null,3,6]
输出:false
解释:根节点的值是 5 ,但是右子节点的值是 4 。
提示:
树中节点数目范围在[1, 10^4] 内
-2^31 <= Node.val <= 2^31 - 1
思路:
二叉搜索树是一颗有序的树,我们可以利用这个很有用的性质
我们知道二叉树的每个结点,它的左子树上的所有结点都小于这个结点,它的右子树上的所有结点都大于这个结点
那么我们使用中序遍历,将这个二叉搜索树中的元素全部存取到数组中,这个数组就是有序的了(如果是二叉搜索树的话)
那么现在我们就转化成了判断一个数组的序列是否有序了
代码:
class Solution {
public:void traversal(TreeNode* root, vector<int>& vec) {if (root == NULL) return;//处理左子树traversal(root->left, vec);//处理中的逻辑vec.push_back(root->val);//处理右子树traversal(root->right, vec);}bool isValidBST(TreeNode* root) {vector<int> vec;traversal(root, vec);for (int i = 1; i < vec.size(); i++) {//找到了无序的序列,就直接返回falseif (vec[i] <= vec[i - 1]) return false;}//否则,返回truereturn true;}
};
另一种方法
其实,这题我们可以不使用数组来记录所有的结点,可以使用一个指针,用来记录上一个访问过的结点,然后比较上一个结点和当前结点的大小,如果不同,就直接返回false,相同则
调用递归函数比较左右子树,如果左右子树有一个为false,则为false,否则就是true
代码
class Solution {
public:TreeNode*pre=NULL;bool isValidBST(TreeNode* root) {if(root==NULL) return true;//递归处理左子树int left=isValidBST(root->left);//如果上一个结点大于当前结点,返回falseif(pre!=NULL&&pre->val>=root->val) return false;//更新pre的值pre=root;int right=isValidBST(root->right);//left和right有一个为假,就是假return left&&right;}
};
迭代法
这题迭代法的代码与第二种的思路很像,也是使用一个指针来存储上一个结点的值
迭代法代码:
class Solution {
public:bool isValidBST(TreeNode* root) {if(root==NULL) return true;stack<TreeNode*> st;TreeNode*pre=NULL;TreeNode*cur=root;while(!st.empty()||cur!=NULL){if(cur!=NULL){st.push(cur);cur=cur->left;}else{cur=st.top();st.pop();//找到比上一个结点大的结点,直接返回falseif(pre!=NULL&&pre->val>=cur->val) return false;pre=cur;cur=cur->right; }}return true;}
};