Границы
validate(node, lower, upper)
Передавай допустимый диапазон вниз по дереву.
В BST все значения слева меньше узла, справа — больше; inorder даёт сортировку.
Минимальный синтаксис, который понадобится в решении.
validate(node, lower, upper)
Передавай допустимый диапазон вниз по дереву.
walk(node.Left)
visit(node)
walk(node.Right)
Обход даёт элементы в возрастающем порядке.
Три идиоматичных решения на Go с оценкой времени и памяти.
Каждый узел должен лежать в диапазоне предков.
O(n) time · O(height) spacefunc isValidBST(root *TreeNode) bool {
var valid func(*TreeNode, int64, int64) bool
valid = func(n *TreeNode, low, high int64) bool {
if n == nil { return true }
v := int64(n.Val)
return low < v && v < high &&
valid(n.Left, low, v) && valid(n.Right, v, high)
}
return valid(root, math.MinInt64, math.MaxInt64)
}
Inorder посещает значения по возрастанию.
O(height + k) time · O(height) spacefunc kthSmallest(root *TreeNode, k int) int {
stack := []*TreeNode{}
for {
for root != nil { stack = append(stack, root); root = root.Left }
root = stack[len(stack)-1]; stack = stack[:len(stack)-1]
k--
if k == 0 { return root.Val }
root = root.Right
}
}
Свойство BST позволяет на каждом шаге отбросить целое поддерево.
O(height) time · O(1) spacefunc searchBST(root *TreeNode, target int) *TreeNode {
for root != nil {
if root.Val == target { return root }
if target < root.Val { root = root.Left } else { root = root.Right }
}
return nil
}