LeetCode 230. 二叉搜索树中第 K 小的元素(迭代中序遍历 + 栈)

一、题目大意

给定一棵二叉搜索树 BST 的根节点root和整数k,找出树里第 k 小的元素,k 从 1 开始计数。

二叉搜索树性质:左子树所有节点 < 当前节点 < 右子树所有节点。 中序遍历(左→根→右)得到的序列是从小到大升序排列。

二、核心解题思想

利用 BST 的特性:中序遍历结果升序。 不需要遍历完整棵树,每访问一个节点就计数,访问到第 k 个节点直接返回,提前终止。

本方案:手动栈模拟中序遍历,找到目标立刻退出,面试优先推荐。

三、迭代(栈)完整代码(AC 版)

ini 复制代码
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public int kthSmallest(TreeNode root, int k) {
        Stack<TreeNode> stack = new Stack<>();
        TreeNode cur = root;
        while(cur != null || !stack.isEmpty()) {
            // 一路向左,整条左链全部入栈
            while(cur != null) {
                stack.push(cur);
                cur = cur.left;
            }
            // 弹出栈顶,访问当前节点(中序:左访问完,访问根)
            cur = stack.pop();
            k--;
            if(k == 0){
                return cur.val;
            }
            // 处理右子树
            cur = cur.right;
        }
        return -1; //语法兜底,题目保证一定有解
    }
}

四、实例演示

样例:root = [5,3,6,2,4,null,null,1],k=3 树结构:

markdown 复制代码
        5
       / \
      3   6
     / \
    2   4
   /
  1

中序序列:1, 2, 3, 4, 5, 6,第 3 小答案为 3

步骤 cur 当前节点 stack(栈底→栈顶) 执行操作 k 的值
1 5 \[\] 内层 while:cur 不为空,压入 5;cur=5.left=3 3
3 5 压入 3;cur=3.left=2 3
2 5,3 压入 2;cur=2.left=1 3
1 5,3,2 压入 1;cur=1.left=null 3
2 null 5,3,2,1 退出内层循环;pop 取出节点 1;k--;k 不等于 0;cur=1.right=null 2
3 null 5,3,2 外层循环,cur=null,pop 取出节点 2;k--;k 不等于 0;cur=2.right=null 1
4 null 5,3 外层循环,cur=null,pop 取出节点 3;k--;k==0,直接返回 3,结束程序 0

五、复杂度分析

  • 时间复杂度:(O(H + k)),H 是树高。最多访问 k 个节点,找到目标就停止,不用遍历整棵树。
  • 空间复杂度:(O(H)),栈最多保存树的一条链,H 为树高;平衡二叉树 H=logn,退化成链表 H=n。

六、易错点清单

  1. ❌ 大小写错误:Stack.isEmpty()(类名调用),正确是stack.isEmpty()(实例对象调用)。
  2. ❌ k 从1 开始计数 ,不是数组下标 0 开始,所以访问节点后k--,判断k==0返回。
  3. ❌ Java 语法坑:有返回值的方法,所有分支必须有 return,末尾需要兜底 return。
  4. ❌ 混淆普通二叉树和 BST:本题必须依赖二叉搜索树的性质,普通二叉树不能直接用中序升序。

七、两种方法对比

方法 优点 缺点
递归中序 代码简短,写得快 找到答案后不会立刻停止,会继续递归,有栈溢出风险
栈迭代中序 找到目标直接退出,可控,面试推荐 代码行数稍多,需要手动维护栈

八、个人感悟

二叉搜索树的中序遍历升序是 BST 题型最核心的考点。 遇到求 BST 第 k 大 / 第 k 小、验证 BST、BST 转有序数组,优先想到中序遍历。迭代写法手动模拟栈,能更好控制遍历终止时机,面试更占优势。

拓展思路:如果树会频繁增删节点,每次重新遍历效率低,可以在树节点中保存子树节点数量,用二分思路直接定位第 k 小,时间优化到(O(H))。

相关推荐
Navigator_Z3 小时前
LeetCode //C - 1283. Find the Smallest Divisor Given a Threshold
c语言·算法·leetcode
我不会起名字3223 小时前
二叉树的遍历与二叉搜索树:把递归、迭代、还原树一次讲透
数据结构·leetcode·二叉树·二叉搜索树
yi0114 小时前
Leetcode 49 用 “身份证‘‘巧解
人工智能·笔记·python·算法·leetcode·哈希表
yi0114 小时前
DAY22: LeetCode 733:图像渲染——从二维网格开始理解 DFS 和 BFS
数据结构·笔记·python·算法·leetcode·深度优先·宽度优先
Pniubi4 小时前
力扣41缺失的第一个正数(哈希表法)
算法·leetcode·职场和发展
Nil2086 小时前
leetcode 70爬楼梯
算法·leetcode·动态规划
longlongzihan8 小时前
LeetCode 189. 轮转数组:从直观模拟到最优原地算法
c++·算法·leetcode
longlongzihan8 小时前
LeetCode 76. 最小覆盖子串:滑动窗口算法详解
算法·leetcode·滑动窗口
All for pursuit.18 小时前
【位运算-1】338.比特位计数
数据结构·c++·算法·leetcode