题目描述
给定一棵二叉搜索树,请找出其中的第k小的结点。
示例
输入:{5,3,7,2,4,6,8},3
返回值:{4}
说明:按结点数值大小顺序第三小结点的值为4。
解题思路
方法一:暴力存储
1、思路:二叉搜索树的中序遍历序列是递增的,因此中序遍历二叉树,将所有结点保存,最后返回第k个结点即可。
2、代码:
/*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};
*/
class Solution {
public:
vector<TreeNode*> list;
void getKthNode(TreeNode *root) {
if (!root) return;
getKthNode(root->left);
list.push_back(root);
getKthNode(root->right);
}
TreeNode* KthNode(TreeNode* pRoot, int k)
{
if (!pRoot || k < 1) return nullptr;
getKthNode(pRoot);
if (k > list.size()) return nullptr;
return list[k - 1];
}
};
3、复杂度:
时间复杂度:O(n);
空间复杂度:O(n)。
方法二:计数器
1、思路:中序遍历递归二叉树,在回溯的过程中,每访问一个结点,就将k值减1,当k为1时,当前结点就是第k小结点。
2、代码:
class Solution {
public:
TreeNode *result = nullptr;
void getKthNode(TreeNode *root, int &k) {
if (!root || k < 1) return;
getKthNode(root->left, k);
if (k == 1) result = root;
if (--k > 0) getKthNode(root->right, k);
}
TreeNode* KthNode(TreeNode* pRoot, int k)
{
if (!pRoot || k < 1) return nullptr;
getKthNode(pRoot, k);
return result;
}
};
3、复杂度:
时间复杂度:O(n);
空间复杂度:O(n)。