给定一个二叉树,判断其是否是一个有效的二叉搜索树。
假设一个二叉搜索树具有如下特征:
- 节点的左子树只包含小于当前节点的数。
- 节点的右子树只包含大于当前节点的数。
- 所有左子树和右子树自身必须也是二叉搜索树。
方法一
中序遍历 + 迭代 时间空间复杂度O(n)
func isValidBST1(_ root: TreeNode?) -> Bool {
if root == nil {
return true
}
var current = root
var stack = [TreeNode]()
var preValue: Int?
while current != nil || !stack.isEmpty {
while let tmp = current {
stack.append(tmp)
current = tmp.left
}
let node = stack.removeLast()
if let tmpPreValue = preValue {
if tmpPreValue >= node.val {
return false
} else {
preValue = node.val
}
} else {
preValue = node.val
}
current = node.right
}
return true
}
方法二
中序遍历 + 递归 时间空间复杂度O(n)
var preValue: Int?
func isValidBST(_ root: TreeNode?) -> Bool {
guard let root = root else {
return true
}
if !isValidBST(root.left) {
return false
}
if let tmpPreValue = preValue {
if tmpPreValue >= root.val {
return false
} else {
preValue = root.val
}
} else {
preValue = root.val
}
if !isValidBST(root.right) {
return false
}
return true
}
方法三
- 在遍历每一个节点的时候,都指定它的上界和下界
- 这种思路适合所有遍历方式
func isValidBST(_ root: TreeNode?) -> Bool {
return isValidBST(root,nil,nil)
}
func isValidBST(_ node: TreeNode?,_ min: Int?,_ max: Int?) -> Bool {
guard let node = node else {
return true
}
if min != nil && node.val <= min! {
return false
}
if max != nil && node.val >= max! {
return false
}
if !isValidBST(node.left, min, node.val) {
return false
}
if !isValidBST(node.right, node.val, max) {
return false
}
return true
}