二叉搜索树中第K小的元素

133 阅读1分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 12 天,点击查看活动详情

给定一个二叉搜索树的根节点 root ,和一个整数 k ,请你设计一个算法查找其中第 k 个最小元素(从 1 开始计数)。

示例 1:

输入:root = [3,1,4,null,2], k = 1 输出:1

示例 2:

输入:root = [5,3,6,2,4,null,null,1], k = 3 输出:3

提示:

树中的节点数为 n 。
1 <= k <= n <= 104
0 <= Node.val <= 104

进阶:如果二叉搜索树经常被修改(插入/删除操作)并且你需要频繁地查找第 k 小的值,你将如何优化算法?

方法一:中序遍历

预备知识

二叉搜索树具有如下性质:

结点的左子树只包含小于当前结点的数。

结点的右子树只包含大于当前结点的数。

所有左子树和右子树自身必须也是二叉搜索树。

二叉树的中序遍历即按照访问左子树——根结点——右子树的方式遍历二叉树;在访问其左子树和右子树时,我们也按照同样的方式遍历;直到遍历完整棵树。

思路和算法

因为二叉搜索树和中序遍历的性质,所以二叉搜索树的中序遍历是按照键增加的顺序进行的。于是,我们可以通过中序遍历找到第 kk 个最小元素。

「二叉树的中序遍历」可以参考「94. 二叉树的中序遍历的官方题解」,具体地,我们使用迭代方法,这样可以在找到答案后停止,不需要遍历整棵树。

代码

    def kthSmallest(self, root: TreeNode, k: int) -> int:
        stack = []
        while root or stack:
            while root:
                stack.append(root)
                root = root.left
            root = stack.pop()
            k -= 1
            if k == 0:
                return root.val
            root = root.right



复杂度分析:

时间复杂度 O(N):中序遍历,每个元素都遍历到,因此复杂度为 O(N)。
空间复杂度 O(N):list中包含了全部元素,因此空间复杂度为O(N).