题目已经描述清楚了二叉搜索树的特征,只要根据特征去验证即可。
有两种思路
- 中序遍历,验证当前节点值大于遍历过程的前一个节点值
- 验证当前子树被限定在一个最小值和一个最大值之间
以下是具体解法。以下代码都已提交通过。
解法一
中序遍历,递归实现。
func isValidBST(root *TreeNode) bool {
var prev *TreeNode
var isValid func(*TreeNode) bool
// 递归调用isValid
isValid = func(root *TreeNode) bool {
// 终止条件
if root == nil {
return true
}
if !isValid(root.Left) {
return false
}
// 处理当前子树根节点
if prev != nil {
// 与前一个节点值做比较
if prev.Val >= root.Val {
return false
}
}
prev = root
return isValid(root.Right)
}
return isValid(root)
}
解法二
中序遍历,迭代法。
func isValidBST(root *TreeNode) bool {
if root == nil {
return true
}
var (
sk Stack
prev *TreeNode
curr = root
)
for {
if curr != nil {
sk.Push(curr)
curr = curr.Left
} else if !sk.IsEmpty() {
node := sk.Peek()
sk.Pop()
// 当前节点和前一个节点做比较
if prev != nil {
if prev.Val >= node.Val {
return false
}
}
prev = node
curr = node.Right
} else {
break
}
}
return true
}
// 栈
type Stack struct {
data []*TreeNode
}
func (o *Stack) Len() int {
return len(o.data)
}
func (o *Stack) IsEmpty() bool {
return len(o.data) == 0
}
func (o *Stack) Push(node *TreeNode) {
o.data = append(o.data, node)
}
func (o *Stack) Peek() *TreeNode {
if o.IsEmpty() {
panic("Stack is empty")
}
return o.data[len(o.data)-1]
}
func (o *Stack) Pop() {
if o.IsEmpty() {
panic("Stack is empty")
}
o.data = o.data[:len(o.data)-1]
}
解法三
先序遍历,递归。
思路就是二叉搜索树的特征,左子树上所有节点的值均小于它的根节点的值,右子树上所有节点的值均大于它的根节点的值。
func isValidBST(root *TreeNode) bool {
return isValid(root, nil, nil)
}
// 递归调用isValid
func isValid(root, min, max *TreeNode) bool {
// 递归终止条件
if root == nil {
return true
}
// 验证当前节点大于最小值
if min != nil {
if root.Val <= min.Val {
return false
}
}
// 验证当前节点小于最大值
if max != nil {
if root.Val >= max.Val {
return false
}
}
// 左子树上所有节点的值均小于它的根节点的值。
// 右子树上所有节点的值均大于它的根节点的值。
if !isValid(root.Left, min, root) ||
!isValid(root.Right, root, max) {
return false
}
return true
}
解法四
中序遍历,递归。思路同解法三。
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func isValidBST(root *TreeNode) bool {
return isValid(root, nil, nil)
}
func isValid(root, min, max *TreeNode) bool {
if root == nil {
return true
}
if !isValid(root.Left, min, root) {
return false
}
if min != nil {
if root.Val <= min.Val {
return false
}
}
if max != nil {
if root.Val >= max.Val {
return false
}
}
return isValid(root.Right, root, max)
}
解法五
后序遍历,递归。思路同解法三。
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func isValidBST(root *TreeNode) bool {
return isValid(root, nil, nil)
}
func isValid(root, min, max *TreeNode) bool {
if root == nil {
return true
}
if !isValid(root.Left, min, root) ||
!isValid(root.Right, root, max) {
return false
}
if min != nil {
if root.Val <= min.Val {
return false
}
}
if max != nil {
if root.Val >= max.Val {
return false
}
}
return true
}