《LeetCode之每日一题》:97.数组中的第K个最大元素

数组中的第K个最大元素


题目链接: 数组中的第K个最大元素

有关题目

给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。

请注意,你需要找的是数组排序后的第 k 个最大的元素,
而不是第 k 个不同的元素。
示例 1:

输入: [3,2,1,5,6,4] 和 k = 2
输出: 5
示例 2:

输入: [3,2,3,1,2,4,5,5,6] 和 k = 4
输出: 4
提示:

1 <= k <= nums.length <= 10^4
-10^4 <= nums[i] <= 10^4

题解

法一:排序

class Solution {
public:
    int findKthLargest(vector<int>& nums, int k) {
        return sort(nums.begin(), nums.end(), greater<int>()), nums[k - 1];
    }
};

时间复杂度:O(nlogn)
空间复杂度:O(logn),递归使用栈空间的空间代价的期望为O(logn)
补充:greater()与less())使用方法

#include<iostream>
#include<algorithm>//因为用了sort()函数
#include<functional>//因为用了greater<int>()
using namespace std;
 
void main()
{
	int a[]={3,1,4,2,5};
	int i;
	int len=sizeof(a)/sizeof(int);//这里切记要除以sizeof(int)!
 
	sort(a ,a + len, greater<int>());//内置类型的由大到小排序
	for(i=0;i<len;i++)
		cout<<a[i]<<" ";
	cout<<"\n";
	sort(a, a + len, less<int>());		//内置类型的由小到大排序
	for(i=0;i<len;i++)
		cout<<a[i]<<" ";
}

方法二:基于堆排序的选择方法

思路:
建立大根堆,做k - 1次删除操作后堆顶元素就是我们要找的答案

//调整
void maxHeapify(int* a, int i, int heapSize)
{
    int l = i * 2 + 1, r = i * 2 + 2, largest = i;//当根节点索引为0,对应的左右孩子节点
    if (l < heapSize && a[l] > a[largest])
        largest = l;
    if (r < heapSize && a[r] > a[largest])
        largest = r;
    if (largest != i)
    {
        int t = a[i];
        a[i] = a[largest],a[largest] = t;//交换
        //当然我们可以自己写个swap(&a[i], &a[largest]),注意传地址哦
        maxHeapify(a, largest, heapSize);调整该节点子树,即往下调整
    }
}
//建堆
void buildMaxHeap(int* a, int heapSize)
{
    for (int i = heapSize / 2; i >= 0; --i)//从最大的非叶子节点开始(len/2),到根节点终止
    {
        maxHeapify(a, i, heapSize);
    }
}
int findKthLargest(int* nums, int numsSize, int k){
    int heapSize = numsSize;//堆的大小
    buildMaxHeap(nums, heapSize);

    //删除,首位元素交换
    for (int i = numsSize - 1; i >= numsSize - k + 1; --i)第k大前面有k - 1个数字,所以删除k - 1个
    {
        int t = nums[0];
        nums[0] = nums[i], nums[i] = t;//交换
        --heapSize;
        maxHeapify(nums, 0, heapSize);//调整
    }
    return nums[0];
}

在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值