题目描述
给定一个二叉搜索树的根节点 root ,和一个整数 k ,请你设计一个算法查找其中第 k 个最小元素(从 1 开始计数)
涉及tag
二叉树
算法思路
二叉搜索树的性质:左子树节点value小于根节点value,右子树节点valu大于根节点value。
结合栈这个数据结构,通过入栈和出栈的顺序从最小到最大返回节点的value。
结合第94题,当k等于0的时候说明已经遍历到第k小的元素。见示例代码1。为避免每一个都遍历,可以比较k和左子树包含元素的大小,讨论:
情况1:k =左子树的节点个数,返回左子树的根节点。
情况2:k > 左子树的节点个数,说明第k小的元素一定在右子树中。将右子树的节点作为根节点,将k重置为k - num(left) - 1,递归进行比较,直到确认在左子树中,根据算法一找到该元素。
情况3:k < 左子树的节点个数,说明第k小的元素一定在左子树中,根据算法一找到该元素。
示例代码
class Solution {
public int kthSmallest(TreeNode root, int k) {
Deque<TreeNode> stack = new ArrayDeque<TreeNode>();
while (root != null || !stack.isEmpty()) {
while (root != null) {
stack.push(root);
root = root.left;
}
root = stack.pop();
k--;
if (k == 0) {
break;
}
root = root.right;
}
return root.val;
}
}
时间复杂度:
O(H+k),其中 H 是树的高度。在开始遍历之前,需要 O(H)到达叶结点。
当树是平衡树时,时间复杂度取得最小值 O(log N + k);当树是线性树(树中每个结点都只有一个子结点或没有子结点)时,时间复杂度取得最大值 O(N+k)。
空间复杂度:O(H),栈中最多需要存储 H 个元素。当树是平衡树时,空间复杂度取得最小值 O(logN);当树是线性树时,空间复杂度取得最大值 O(N)。