LeetCode98. 验证二叉搜索树
1.力扣151. 反转字符串中的单词2.LeetCode515.在每个树行中找最大值3.LeetCode104.二叉树的最大深度4.LeetCode111.二叉树的最小深度5.LeetCode136. 只出现一次的数字6.LeetCode260. 只出现一次的数字 III7.LeetCode151. 反转字符串中的单词8.LeetCode225. 用队列实现栈9.LeetCode102.二叉树的层序遍历10.LeetCode107.二叉树的层序遍历II11.LeetCode199.二叉树的右视图12.LeetCode637.二叉树的层平均值13.LeetCode226. 翻转二叉树14.LeetCode455.分发饼干15.LeetCode860. 柠檬水找零16.LeetCode122. 买卖股票的最佳时机 II17.LeetCode1005. K 次取反后最大化的数组和18.LeetCode53. 最大子数组和19.LeetCode513. 找树左下角的值20.LeetCode135. 分发糖果21.LeetCode222.完全二叉树的节点个数22.LeetCode700. 二叉搜索树中的搜索
23.LeetCode98. 验证二叉搜索树
24.LeetCode530. 二叉搜索树的最小绝对差25.LeetCode654. 最大二叉树26.LeetCode617. 合并二叉树27.回溯算法介绍以及模板28.LeetCode216.组合总和lll29.LeetCode39. 组合总和30.LeetCode40.组合总和II31.动态规划方法论32.线性dp:编辑距离33.线性dp:大盗阿福(打家劫舍)34.LeetCode300.最长递增子序列35.线性dp:LeetCode674. 最长连续递增序列36.线性dp:LeetCode516 .最长回文子序列37.线性dp:LeetCode122.买卖股票的最佳时机ll题目链接: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++) { //找到了无序的序列,就直接返回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; } };
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了