LC230 - 二叉搜索树中第K小的元素
| KthSmallestElementInABST.go |
|---|
| package BinaryTree
type BSTWithCnt struct {
root *TreeNode
cnt map[*TreeNode]int
}
func (bst *BSTWithCnt) Init(root *TreeNode) {
bst.root = root
bst.cnt = make(map[*TreeNode]int)
bst.count(root)
}
func (bst *BSTWithCnt) count(node *TreeNode) int {
if node == nil {
return 0
}
ret := bst.count(node.Left) + bst.count(node.Right) + 1
bst.cnt[node] = ret
return ret
}
func (bst *BSTWithCnt) Findkth(k int) int {
return bst.find(bst.root, k)
}
func (bst *BSTWithCnt) find(node *TreeNode, k int) int {
leftCnt := bst.cnt[node.Left]
if leftCnt == k-1 {
return node.Val
} else if leftCnt < k-1 {
return bst.find(node.Right, k-leftCnt-1)
} else {
return bst.find(node.Left, k)
}
}
// 时间复杂度: O(h), 空间复杂度: O(n)
// h表示BST的高度, n表示BST节点总数
func kthSmallest(root *TreeNode, k int) int {
bst := new(BSTWithCnt)
bst.Init(root)
return bst.Findkth(k)
}
|
中序遍历的方法就不说了,其时间复杂度为O(h + k)。当需要频繁查找第K小的元素时,通过生成预处理结构BSTWithCnt(时间复杂度为O(n)),可以将每次查找的时间复杂度降至O(h)。