给定一棵二叉搜索树,请找出其中第k大的节点。
示例 1:
输入: root = [3,1,4,null,2], k = 1
3
/ \
1 4
\
2
输出: 4
示例 2:
输入: root = [5,3,6,2,4,null,null,1], k = 3
5
/ \
3 6
/ \
2 4
/
1
输出: 4
限制:
1 ≤ k ≤ 二叉搜索树元素个数
递归解法:
思路:先按中序遍历将二叉搜索树的结点值从小到大的顺序保存在vec数组中,然后直接输出第k大的值。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
int kthLargest(TreeNode* root, int k) {
vector<int> vec;
inorder(root, vec);
return vec[vec.size() - k];
}
void inorder(TreeNode* node, vector<int>& vec) {
//中序遍历,将节点按从小到大顺序保存在vec中
if (node->left)
inorder(node->left, vec);
vec.push_back(node->val);
if (node->right)
inorder(node->right, vec);
}
};
非递归解法:
思路:类似于中序遍历的非递归算法,但是访问结点的顺序为:右子结点 -> 父节点 -> 左子结点。首先设定一个计数器cnt = 1, 然后循环向右遍历结点,将访问到的结点顺序压入栈中,直到右子结点为空。然后出栈,只要当前计数器cnt等于k,则找到了第k大的结点,否则计数器加1,再向当前出栈结点的左子树遍历。若看不懂可以先去了解二叉树遍历的非递归算法。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
int kthLargest(TreeNode* root, int k) {
vector<int> vecInt;
stack<TreeNode*> s;
TreeNode* node = root;
int cnt = 1;
while (node || !s.empty()) {
while (node) {
//向右遍历获取值最大的结点
s.push(node);
node = node->right;
}
if (!s.empty()) {
//出栈判断
node = s.top();
if (cnt == k)
return node->val;
else
++cnt;
s.pop();
//向当前出栈结点的左子树重复上述步骤
node = node->left;
}
}
return 0;
}
};