遇到二叉搜索树(BST)相关问题时,首先要明确BST的核心特性:对于任意节点,其左子树所有节点值小于该节点值,右子树所有节点值大于该节点值。这个性质直接决定了我们查找第K小元素的策略。
给定一个BST的根节点和一个整数k,要求找出树中第k小的元素值。注意k从1开始计数。例如对于BST [3,1,4,null,2],当k=3时,应返回3。
解决这个问题主要有两种经典方法:
python复制class Solution:
def kthSmallest(self, root: Optional[TreeNode], k: int) -> int:
self.res = None
self.count = 0
def inorder(node):
if not node or self.res is not None:
return
inorder(node.left)
self.count += 1
if self.count == k:
self.res = node.val
return
inorder(node.right)
inorder(root)
return self.res
时间复杂度:O(H + k),其中H是树的高度。最坏情况下需要遍历整个树(当k=N时)。
空间复杂度:O(H),递归调用栈的深度取决于树的高度。
注意:虽然递归写法简洁,但在最坏情况下(树退化为链表)空间复杂度会达到O(N),对于大型树可能引发栈溢出。
python复制class Solution:
def kthSmallest(self, root: Optional[TreeNode], k: int) -> int:
stack = []
curr = root
while stack or curr:
while curr:
stack.append(curr)
curr = curr.left
curr = stack.pop()
k -= 1
if k == 0:
return curr.val
curr = curr.right
如果需要频繁查询不同k值,可以考虑预处理:
当树结构可能被修改(插入/删除节点)时,可以采用以下策略:
BST的排序特性使其在以下场景有重要应用:
理解如何高效查找BST中的第k小元素,是掌握这些高级应用的基础。在实际工程中,我们往往会根据数据规模和查询模式选择适当的变种算法。