描述
给定一棵二叉搜索树,请找出其中的第k小的TreeNode结点。
示例1
输入: {5,3,7,2,4,6,8},3
返回值: 4
说明: 按结点数值大小顺序第三小结点的值为4
思路
根据二叉搜索树的性质,其中序遍历是由大到小的,由此仅需要中序遍历找到第k个小的结点即可。
中序遍历具体做法:
用栈记录当前结点,不断往左深入,直到左边子树为空,再弹出栈顶(即为当前子树的父结点),然后再访问其右子树,其中每棵子树都遵循左中右的次序。
时间复杂度:O(n),每个结点遍历一遍
空间复杂度:O(n),栈空间最大值
代码1:栈
/*
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}
*/
import java.util.Stack;
public class Solution {
TreeNode KthNode(TreeNode pRoot, int k) {
if(pRoot == null || k <= 0) {
return null;
}
int count = 0;
Stack<TreeNode> stack = new Stack<>();
while(!stack.isEmpty() || pRoot != null) {
//中序遍历每棵子树从最左开始
while(pRoot != null) {
stack.add(pRoot);
pRoot = pRoot.left;
}
TreeNode node = stack.pop();
count++;
if (count == k) {
return node;
}
pRoot = node.right;
}
return null;
}
}
代码2:递归
class Solution {
public:
TreeNode* res = NULL;//记录返回的结点
int count = 0;//记录中序遍历了多少个
void midOrder(TreeNode* root, int k){
if(root == NULL || count > k) //当遍历到结点为空或者超过k时,返回
return;
midOrder(root->left, k);
count++;
if(count == k) //只记录第k个
res = root;
midOrder(root->right, k);
}
TreeNode* KthNode(TreeNode* pRoot, int k) {
midOrder(pRoot, k);
return res;
}
};