题目:
在未排序的数组中找到第 k 个最大的元素。请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。
示例 1:
输入: [3,2,1,5,6,4] 和 k = 2
输出: 5
思路:
对于寻找最大值的可往最大堆和最小堆思考,笔者是通过最小堆的方式解答。
这里先引入最小堆的概念。最小堆,是一种经过排序的完全二叉树,其中任一非终端节点的数据值均不大于其左子节点和右子节点的值。
简而言之就是根结点的键值是所有堆结点键值中最小者。
如图所示
二叉树的最小值就在跟节点处。
我们可以创建一个k大小的最小堆,如果最小堆的大小 小于 k,新元素就添加到最小堆内,否则,如果新元素大于堆顶元素,则弹出堆顶元素,将新元素添加到最小堆内。
接下来举例子说明:
示例 1:
输入: [3,2,1,5,6,4] 和 k = 2
输出: 5
1.由于最小堆的大小为0,小于k=2值将数组第一个数 3 插入二叉树。
2.由于最小堆的大小为1,小于k=2值将数组第二个数 3 插入二叉树
3.由于上面已经插入了两个数据,不满足小于k值,不会添加新元素,则会判断第三个数是否大于堆顶,第三个数 1 小于堆顶元素,则不会进入最小堆。
4.由于已经插入2个数据,且第四个数据5满足大于栈顶元素,则先弹出栈顶元素,再插入第四个数据5。
注意:最小堆会自动排序,最小的数会在根节点
5.由于已经插入2个数据,且第五个数据5满足大于栈顶元素,则先弹出栈顶元素,再插入第五个数据 6 。
6.由于已经插入2个数据,且第六个数据 4 小于栈顶元素,不会插入第六个数据。
7.最后再返回栈顶元素,则为第k大的元素。
C++代码实现:
class Solution {
public:
int findKthLargest(vector<int>& nums, int k) {
//定义一个最小堆
std::priority_queue<int,std::vector<int>,std::greater<int>>q;
for(int i=0;i<nums.size();i++)//循环判断数组内的数据
{
if(q.size()<k)//最小堆大小小于k时
{
q.push(nums[i]);
}
else if(q.top()<nums[i])//判断栈顶最小值是否小于新元素
{
q.pop();//弹出栈顶元素
q.push(nums[i]);//将新元素添加到最小堆内
}
}
return q.top();//返回栈顶元素即为所得值
}
};