1、题目
2、题解
吃一堑长一智,赶快去看树的数据结构有没有给,毕竟给数组还是给定义好的数据结构难度差别有点大,树的信息通过指定的数据结构进行存储,节点数范围 [1, 10^4]。
已知的一些算法回溯,动态规划,滑动窗口,双指针,栈,想来想去还是先试试回溯吧,就是怕时间又超出限制,代码如下
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func isValidBST(root *TreeNode) bool {
var checkTree func (r *TreeNode, left, right int) bool
checkTree = func (r *TreeNode, left, right int) bool{
l1,r1:=left, right
if r.Left==nil && r.Right==nil{ // 叶子节点
return r.Val>left && r.Val<right
}else if r.Left==nil{ // 右子树
if r.Val>left {l1=r.Val}
return (r.Val>left && r.Val<right) && checkTree(r.Right, l1, right)
}else if r.Right==nil{ // 左子树
if r.Val<right {r1=r.Val}
return (r.Val>left && r.Val<right) && checkTree(r.Left, left, r1)
}else{
if r.Val>left {l1=r.Val}
if r.Val<right {r1=r.Val}
return (r.Val>left && r.Val<right) && checkTree(r.Left, left, r1) && checkTree(r.Right, l1, right)
}
}
return checkTree(root, math.MinInt32-1, math.MaxInt32+1)
}
bug1:
最先开始递归体判断 r.Val>r.Left.Val && r.Val<r.Right.Val,即比较当前节点与它的左右节点,在下图所示情况踩坑,节点6判断满足条件,但是忽略3<5,不满足节点5右子树的要求。
改正:使用逆向比较,对节点6,不再比较其子节点,而是与其父节点方向的节点比较,保证6大于左边最大值,小于右边最小值
bug2:因为节点范围 ,所以直接用了math.MinInt32 和 math.MaxInt32作为初始值,却忽略了=号的情况
改正:初始值使用 math.MinInt32-1和math.MaxInt32+1
提交结果如下:这结果可太差了
思考改进方式:看题解
1)递归:与我的思路类似,但更为精简
2)中序遍历,二叉搜索树的中序遍历结果一定是升序排列的,题解中的代码如下(提供了借助栈实现中序遍历的方法)
func isValidBST(root *TreeNode) bool {
stack := []*TreeNode{}
inorder := math.MinInt64
for len(stack) > 0 || root != nil {
for root != nil {
stack = append(stack, root)
root = root.Left
}
root = stack[len(stack)-1]
stack = stack[:len(stack)-1]
if root.Val <= inorder {
return false
}
inorder = root.Val
root = root.Right
}
return true
}
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/validate-binary-search-tree/solution/yan-zheng-er-cha-sou-suo-shu-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。