题目描述
给定一棵二叉搜索树,请找出其中的第k小的TreeNode结点。
示例1
输入:{5,3,7,2,4,6,8},3
返回值:4
说明:按结点数值大小顺序第三小结点的值为4
题目分析
想要获得第k小的结点,可以对二叉搜索树进行中序遍历(左-根-右),使用count计算从最左边(最小结点)开始,每经过一个结点,count加1,直到count == k,当前结点即为目标结点。
解题思路
方法1:递归法
中序遍历树,可以直接使用递归方法,同时使用一个全局TreeNode来记录结果结点,以及count来统计已经访问的结点个数。
方法2:非递归
中序遍历树,可以通过stack进行非递归遍历,同理使用count来统计访问的结点个数,当count==k时,当前结点即为目标结点。
代码实现
方法1:递归法
TreeNode res = null;
int count = 0;
TreeNode KthNode(TreeNode pRoot, int k) {
if(pRoot == null || count > k) return null;
KthNode(pRoot.left, k);
// 中序遍历,从最左结点开始计算个数
count++;
if(count == k){
// 当已经遍历到了第k个结点,直接返回
res = pRoot;
return res;
}
// 左边结点数小于k,继续遍历右边的
KthNode(pRoot.right, k);
return res;
}时间复杂度:O(n),在递归过程中,至少需要遍历树中的k个结点,最差情况是遍历全部的结点;
空间复杂度:O(n),栈的递归深度与遍历的结点数相同,最差是整个树的结点数量n;
方法2:非递归
TreeNode KthNode(TreeNode pRoot, int k) {
if(k<=0) return null;
TreeNode res = null;
// 使用栈来循环遍历树
Stack<TreeNode> stack = new Stack<TreeNode>();
int count = 0;
// 循环中序遍历二叉树
while(pRoot!=null || !stack.isEmpty()){
while(pRoot != null){
// 中序遍历,将根节点先放入栈中,直到最左结点
stack.push(pRoot);
pRoot = pRoot.left;
}
if(!stack.isEmpty()){
// 从最左节点开始计数
TreeNode tem = stack.pop();
count++;
if(count == k){
res = tem;
break;
}
pRoot = tem.right;
}
}
return res;
}时间复杂度:O(n),在循环过程中,至少需要遍历树中的k个结点,最差情况是遍历全部的结点;
空间复杂度:O(n),栈中最多存储整个树的结点数量n。

京公网安备 11010502036488号