Leetcode 二叉搜索树的第 K 个元素

在这里插入图片描述
复习一下二叉搜索树
二叉搜索树 (Binary Search Tree, 简称 BST) 是一种特殊的二叉树(可以为空),其中每个节点都有一个值,并且满足以下特点:

定义:

  1. 左子树节点的值小于根节点的值:对于每个节点,左子树中所有节点的值都小于该节点的值。
  2. 右子树节点的值大于根节点的值:对于每个节点,右子树中所有节点的值都大于该节点的值。
  3. 左右子树本身也是二叉搜索树:即递归地应用上述规则,左子树和右子树也必须是二叉搜索树。

特点:

  1. 查找效率高:在理想情况下(树的高度接近平衡时,即左右子树高度接近),二叉搜索树的查找、插入、删除操作的时间复杂度为 O ( log ⁡ n ) O(\log n) O(logn),其中 n n n 是树中的节点数。
  2. 有序性:二叉搜索树的中序遍历会按升序输出节点的值,因此可以用来进行排序或快速查找最大、最小值。
  3. 插入和删除:插入新节点和删除节点时,需要遵循二叉搜索树的规则,确保树的有序性。
  4. 平衡性问题:在极端情况下(如连续插入升序或降序的值),二叉搜索树可能会退化为一条链表,此时树的高度为 O ( n ) O(n) O(n),查找、插入和删除的时间复杂度将退化为 O ( n ) O(n) O(n)
  5. 空间复杂度:使用指针结构,空间复杂度通常为 O ( n ) O(n) O(n),其中 n n n 是节点数。

注意:为了避免二叉搜索树退化为链表,一些平衡二叉搜索树如红黑树 (Red-Black Tree) 或 AVL 树等会动态保持树的平衡性,确保操作的时间复杂度为 O ( log ⁡ n ) O(\log n) O(logn)

算法思想:

  1. 二叉搜索树的性质:二叉搜索树(BST)有一个重要性质:左子树的所有节点值都小于根节点,右子树的所有节点值都大于根节点。因此,对二叉搜索树进行中序遍历(先左子树 -> 根节点 -> 右子树),会按升序依次访问每个节点的值。

  2. 中序遍历的过程可以确保我们从最小的节点开始访问,并依次访问较大的节点。因此,当我们访问到第 k 个节点时,该节点即为树中第 k 小的元素。

java solution

class Solution {
    private int count = 0;
    private int result = 0;
    public int kthSmallest(TreeNode root, int k) {
        inorderTraversal(root, k);
        return result;
    }
    private void inorderTraversal(TreeNode root, int k) {
        if(root == null) {
            return;
        }
        // 递归遍历左子树
        inorderTraversal(root.left, k);

        // 访问当前节点
        count++;
        if(count == k) {
            result = root.val;
            return; //找到结果后可以直接返回
        }

        // 递归遍历右子树
        inorderTraversal(root.right, k);
    }
}
<think>好的,我现在需要帮用户找到关于二叉搜索树的相关例题或练习。首先,用户提供了几个参考引用,都是关于LeetCode上的二叉搜索树题目和解析。我需要先理解这些引用的内容,然后结合用户的需求,生成相关的练习题和示例。 首先,用户提到的引用[1]到[4]都是关于二叉搜索树的不同题目,比如删除节点、验证BST、修剪BST、中序遍历迭代器等。这些题目覆盖了BST的基本操作和常见应用。用户希望得到相关的例题或练习,可能是在准备面试或者算法学习,特别是针对二叉搜索树的结构和操作。 接下来,我需要根据这些引用中的题目,生成相关问题。例如,验证二叉搜索树的有效性、删除节点、修剪BST、中序遍历的应用等。同时,用户可能需要示例代码和解题思路,所以每个问题需要给出简要的步骤和代码示例,确保符合用户的要求。 还要注意系统级指令中的要求,比如行内公式用$...$,独立公式用$$...$$,使用中文回答,并且生成相关问题。在回答中引用用户提供的参考文献,末尾自然添加引用标识。例如,在讲删除节点时,引用[2],修剪BST时引用[3]等。 需要确保每个问题都有对应的解题思路和代码示例,并且代码格式正确,用Python实现。同时,回答的结构要清晰,分点列出问题和解答,帮助用户逐步理解。 最后,用户可能还希望了解这些题目的应用场景或者进一步的问题,因此在相关问题部分可以提出更深层次的问题,比如时间复杂度分析、不同方法的优缺点等,引导用户进一步思考和学习。 总结一下,我需要整理用户提供的引用中的题目,将其转化为结构化的练习题,每个题目附上解题思路、关键点和代码示例,并正确引用来源。同时,生成的相关问题要覆盖BST的常见操作和应用,帮助用户系统性地练习和掌握相关知识。</think>### 二叉搜索树相关例题与练习 #### 1. 验证二叉搜索树LeetCode 98) **问题描述** 给定一个二叉树的根节点,验证其是否为有效的二叉搜索树(BST)。 **解题思路** - BST的定义:左子树所有节点值 < 根节点值 < 右子树所有节点值,且左右子树也必须是BST[^3]。 - 中序遍历BST会得到一个严格递增序列,利用此性质验证。 **代码示例** ```python class Solution: def isValidBST(self, root: Optional[TreeNode]) -> bool: def inorder(node, lower=float('-inf'), upper=float('inf')): if not node: return True if not (lower < node.val < upper): return False return inorder(node.left, lower, node.val) and inorder(node.right, node.val, upper) return inorder(root) ``` --- #### 2. 删除二叉搜索树中的节点(LeetCode 450) **问题描述** 给定BST的根节点和一个值`key`,删除对应的节点并保持BST性质[^2]。 **关键步骤** - 若节点为叶子节点,直接删除。 - 若节点有一个子节点,用子节点替代。 - 若节点有两个子节点,找到右子树的最小值节点或左子树的最大值节点替换。 **代码示例** ```python class Solution: def deleteNode(self, root: Optional[TreeNode], key: int) -> Optional[TreeNode]: if not root: return None if root.val > key: root.left = self.deleteNode(root.left, key) elif root.val < key: root.right = self.deleteNode(root.right, key) else: if not root.left: return root.right if not root.right: return root.left min_node = root.right while min_node.left: min_node = min_node.left root.val = min_node.val root.right = self.deleteNode(root.right, min_node.val) return root ``` --- #### 3. 修剪二叉搜索树LeetCode 669) **问题描述** 给定BST的根节点和区间`[low, high]`,修剪树使得所有节点值在此范围内[^3]。 **解题思路** - 若当前节点值小于`low`,则其左子树均不满足,递归处理右子树。 - 若当前节点值大于`high`,递归处理左子树。 - 否则递归处理左右子树。 **代码示例** ```python class Solution: def trimBST(self, root: Optional[TreeNode], low: int, high: int) -> Optional[TreeNode]: if not root: return None if root.val < low: return self.trimBST(root.right, low, high) if root.val > high: return self.trimBST(root.left, low, high) root.left = self.trimBST(root.left, low, high) root.right = self.trimBST(root.right, low, high) return root ``` --- #### 4. 二叉搜索树中第K小的元素LeetCode 230) **问题描述** 找到BST中第$k$小的元素。 **解题思路** 利用中序遍历的递增性质,遍历到第$k$个节点时返回结果[^1][^4]。 **代码示例** ```python class Solution: def kthSmallest(self, root: Optional[TreeNode], k: int) -> int: stack = [] while stack or root: while root: stack.append(root) root = root.left root = stack.pop() k -= 1 if k == 0: return root.val root = root.right ``` --- #### 5. 二叉搜索树迭代器(LeetCode 173) **问题描述** 设计一个迭代器,实现中序遍历的`next()`和`hasNext()`操作。 **实现方法** - 非递归中序遍历,用栈保存左子树路径。 **代码示例** ```python class BSTIterator: def __init__(self, root: Optional[TreeNode]): self.stack = [] self._push_left(root) def _push_left(self, node): while node: self.stack.append(node) node = node.left def next(self) -> int: node = self.stack.pop() self._push_left(node.right) return node.val def hasNext(self) -> bool: return len(self.stack) > 0 ``` --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值