LeetCode 98. 验证二叉搜索树
1.LeetCode 203. 移除链表元素2.LeetCode 206. 反转链表3.LeetCode 24. 两两交换链表中的节点4.LeetCode 19. 删除链表的倒数第 N 个结点5.LeetCode 160. 相交链表6.LeetCode 142. 环形链表 II7.LeetCode 242. 有效的字母异位词8.LeetCode 349. 两个数组的交集9.LeetCode 202. 快乐数10.LeetCode 704. 二分查找 题解11.LeetCode 27. 移除元素 题解12.LeetCode 977. 有序数组的平方13.LeetCode 209. 长度最小的子数组14.LeetCode 59. 螺旋矩阵 II15.LeetCode 1. 两数之和16.LeetCode 454. 四数相加 II17.LeetCode 383. 赎金信18.LeetCode 15. 三数之和19.LeetCode 18. 四数之和20.LeetCode 76. 最小覆盖子串21.LeetCode 344. 反转字符串22.LeetCode 541. 反转字符串 II23.LeetCode 剑指 Offer 05. 替换空格24.LeetCode 151. 反转字符串中的单词25.LeetCode 剑指 Offer 58 - II. 左旋转字符串26.LeetCode 459. 重复的子字符串27.kmp算法详解28.LeetCode 20. 有效的括号29.LeetCode 1047. 删除字符串中的所有相邻重复项30.LeetCode 150. 逆波兰表达式求值31.LeetCode 239. 滑动窗口最大值32.LeetCode 347. 前 K 个高频元素33.LeetCode 94. 二叉树的中序遍历34.LeetCode 144. 二叉树的前序遍历35.LeetCode 145. 二叉树的后序遍历36.LeetCode 102. 二叉树的层序遍历37.LeetCode 226. 翻转二叉树38.LeetCode 101. 对称二叉树39.LeetCode 104. 二叉树的最大深度40.LeetCode 559. N 叉树的最大深度41.LeetCode 111. 二叉树的最小深度42.LeetCode 222. 完全二叉树的节点个数43.LeetCode 110. 平衡二叉树44.LeetCode 257. 二叉树的所有路径45.LeetCode 404. 左叶子之和46.LeetCode 513. 找树左下角的值47.LeetCode 112. 路径总和48.LeetCode 113. 路径总和 II49.LeetCode 106. 从中序与后序遍历序列构造二叉树50.LeetCode 105. 从前序与中序遍历序列构造二叉树51.LeetCode 654. 最大二叉树52.LeetCode 617. 合并二叉树53.LeetCode 700. 二叉搜索树中的搜索
54.LeetCode 98. 验证二叉搜索树
55.LeetCode 530. 二叉搜索树的最小绝对差56.LeetCode 501. 二叉搜索树中的众数57.LeetCode 236. 二叉树的最近公共祖先58.LeetCode 235. 二叉搜索树的最近公共祖先59.LeetCode 701. 二叉搜索树中的插入操作60.LeetCode 450. 删除二叉搜索树中的节点61.LeetCode 669. 修剪二叉搜索树62.LeetCode 108. 将有序数组转换为二叉搜索树63.LeetCode 538. 把二叉搜索树转换为累加树64.LeetCode 131. 分割回文串题目链接:LeetCode 98. 验证二叉搜索树
题意:
给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。
有效 二叉搜索树定义如下:
- 节点的左子树只包含 小于 当前节点的数。
- 节点的右子树只包含 大于 当前节点的数。
- 所有左子树和右子树自身必须也是二叉搜索树。
解题思路:
递归法1
由二叉搜索树的性质可知,中序遍历的结果是有序的,因此可以利用这个性质来判断当前二叉树是否是二叉搜索树。
代码:
var res []int //存放二叉树中所有节点中序遍历的值
func isValidBST(root *TreeNode) bool {
res = []int{}
dfs(root)
for i:=1;i<len(res);i++{
if res[i] <= res[i-1]{
return false
}
}
return true
}
func dfs(root *TreeNode){
if root == nil {
return
}
dfs(root.Left)
res = append(res,root.Val)
dfs(root.Right)
}
这道题目比较容易陷入两个陷阱:
陷阱1
不能单纯的比较左节点小于中间节点,右节点大于中间节点就完事了。
写出了类似这样的代码:
if (root->val > root->left->val && root->val < root->right->val) {
return true;
} else {
return false;
}
我们要比较的是 左子树所有节点小于中间节点,右子树所有节点大于中间节点。所以以上代码的判断逻辑是错误的。
陷阱2
样例中最小节点 可能是int的最小值,如果这样使用最小的int来比较也是不行的。
此时可以初始化比较元素为longlong的最小值。
递归法2
中序遍历二叉树,判断当前节点的值是否严格大于前一个结点
func isValidBST(root *TreeNode) bool {
var pre *TreeNode // 用来记录中序遍历时的前一个节点
var travel func(root *TreeNode)bool
travel = func(root *TreeNode)bool{
if root == nil {
return true
}
left := travel(root.Left)
if pre != nil && pre.Val >= root.Val{
return false
}
pre = root;
right := travel(root.Right)
return left && right
}
return travel(root)
}
LC示例代码
func isValidBST(root *TreeNode) bool {
// 由题目中的数据限制可以得出min和max
return check(root,math.MinInt,math.MaxInt)
}
func check(node *TreeNode,min,max int) bool {
// 二叉搜索树也可以是空树
if node == nil {
return true
}
if min >= node.Val || max <= node.Val {
return false
}
// 分别对左子树和右子树递归判断,如果左子树和右子树都符合则返回true
return check(node.Right,node.Val,max) && check(node.Left,min,node.Val)
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了