跳转至

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)。