刷题使我快乐,满脸开心.jpg
- 来源:力扣(LeetCode)
- 链接:https://leetcode.cn/problems/kth-smallest-element-in-a-bst/
- 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
题目
给定一个二叉搜索树的根节点 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 <= 10^4
0 <= Node.val <= 10^4
进阶:如果二叉搜索树经常被修改(插入/删除操作)并且你需要频繁地查找第
k
小的值,你将如何优化算法?
思路
首先明确二叉搜索树性质
二叉搜索树性质
- 根结点的值大于所有左子树中节点的值
- 根结点的值小于所有右子树中节点的值
所以其实找第k
小的值,也就是在二叉树的中序遍历
结果中找第k
小的元素。
优化
所谓优化,无非时间复杂度和空间复杂度。
而对应优化的方向有两个:
- 不完全遍历完就可以出结果
- 不存储遍历结果,只取关心的结果
而我们在遍历时其实本身就
能够感知到遍历到的是第几个数
,因此只需要维护一个计数值
,到第K个数时中断遍历
,返回当前的值即可
至此,细节详见代码注释
代码
func kthSmallest(root *TreeNode, k int) int {
res := 0
var dfs func(root *TreeNode)
dfs = func(root *TreeNode) {
// 中序遍历, 遍历左子树
if root.Left != nil {
dfs(root.Left)
}
// 中序遍历, 遍历完左子树后遍历根节点
k--
// 减为0说明找到了第K个值,赋值返回
if k == 0 {
res = root.Val
return
}
// 中序遍历, 遍历右子树
if root.Right != nil {
dfs(root.Right)
}
}
dfs(root)
return res
}