给定一棵二叉搜索树,请找出其中第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 ≤ 二叉搜索树元素个数
思路
维护一个大小为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:
// 堆调整
void heapAdjust(vector<int>& heap, int l){
int parent= l, r= heap.size();
int child= 2*parent+ 1;
while(child< r){
if(child+ 1< r&& heap[child]> heap[child+ 1])
child++;
if(heap[parent]<= heap[child])
return;
else{
swap(heap[parent], heap[child]);
parent= child;
child= 2*parent+ 1;
}
// cout<<child<<endl;
}
}
// 堆排
void heapSort(vector<int>& heap){
int size= heap.size();
for(int i= size/ 2- 1; i>= 0; i--){
heapAdjust(heap, i);
}
}
int kthLargest(TreeNode* root, int k) {
vector<int> heap;
int tempk= k;
queue<TreeNode*> qu;
qu.push(root);
TreeNode* temp;
while(tempk--){
temp= qu.front();
qu.pop();
heap.push_back(temp->val);
if(temp->left) qu.push(temp->left);
if(temp->right) qu.push(temp->right);
}
// 初始化小顶堆
heapSort(heap);
// 跟后续的节点进行比较并进行堆调整
while(!qu.empty()){
temp= qu.front();
qu.pop();
if(temp->left) qu.push(temp->left);
if(temp->right) qu.push(temp->right);
if(temp->val> heap[0]){
heap[0]= temp->val;
heapAdjust(heap, 0);
}
}
return heap[0];
}
};
参考Leetcode题解,
利用了二叉搜索树所有左子树都小于根节点 ,右子树都大于等于根节点的性质,直接使用中序遍历来求
/**
* 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 K;
int result;
// 中序遍历查找
void findK(TreeNode* root){
if(!root|| result) return;
findK(root->right);
// K等于0说明已经找到了
if(!K) return;
K--;
result= K? 0: root->val;
findK(root->left);
}
int kthLargest(TreeNode* root, int k) {
K= k;
result= 0;
findK(root);
return result;
}
};