LeetCode98. 验证二叉搜索树

题目链接:https://leetcode.cn/problems/validate-binary-search-tree/description/

题目叙述:

给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。

有效二叉搜索树定义如下:

  1. 节点的左子树只包含 小于 当前节点的数。
  2. 节点的右子树只包含 大于 当前节点的数。
  3. 所有左子树和右子树自身必须也是二叉搜索树。

示例 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++) {
			//找到了无序的序列,就直接返回false
			if (vec[i] <= vec[i - 1]) return false;
		}
		//否则,返回true
		return 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);
        //如果上一个结点大于当前结点,返回false
        if(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();
            //找到比上一个结点大的结点,直接返回false
                if(pre!=NULL&&pre->val>=cur->val) return false;
                pre=cur;
                cur=cur->right; 
            }
        }
        return true;
    }
};
posted @ 2024-07-29 02:22  Tomorrowland_D  阅读(69)  评论(0)    收藏  举报