数据结构与算法——Leetcode215. 数组中的第K个最大元素
题目链接:215. 数组中的第K个最大元素
题目:
①直接排序
class Solution {
public:int findKthLargest(vector<int>& nums, int k) {sort(nums.begin(), nums.end());int n = nums.size();return nums[n - k];}
};
当然,写算法题不能止步于依赖库,而且其时间复杂度也不符合要求。
时间复杂度:
②随机选择排序
class Solution {
public:int findKthLargest(vector<int>& nums, int k) {//找第k大,即为找排序后下标为size - k的数return randomSelect(nums, nums.size() - k);}//找到数组排序后k位置的数int randomSelect(vector<int>& nums, int k) {int l = 0, r = nums.size() - 1;int ans;while(l <= r){//在[l, r]区间上随机选择一个数字int x = nums[l + rand() % (r - l + 1)];//得到x在当前区间内排序后的左右区间下标auto lmt = partition(nums, l, r, x);if(lmt.first > k){//如果这个区间左边界比k大//说明我们要找的位置在该区间左边r = lmt.first - 1;}else if(lmt.second < k){//如果这个区间右边界比k小//说明我们要找的位置在该区间右边l = lmt.second + 1;}else{//如果k位置就在当前区间//记录结果ans = nums[k];break;}}return ans;}pair<int, int> partition(vector<int>& nums, int l, int r, int x){//区间边界int a = l, b = r;//循环区间内的数字for(int i = a; i <= b; ++i){if(nums[i] < x){//如果当前i位置数字比x小//则将其换至区间最左边swap(nums, a, i);a++;}else if(nums[i] > x){//如果当前i位置数字比x大//则将其换至区间最右边//但是从区间右边换来的新数字我们并没有遍历过//所以i--swap(nums, b, i);b--;i--;}//如果i位置的数字等于x,则不动}//最后[a, b]区间内即为等于x的数字return {a, b};}void swap(vector<int>& nums, int i, int j){int temp = nums[i];nums[i] = nums[j];nums[j] = temp;}
};
③优先队列(堆)
class Solution {
private:struct compare {bool operator()(int a, int b) { return a > b; }};public:int findKthLargest(vector<int>& nums, int k) {// 直接用数组初始化小顶堆priority_queue<int, vector<int>, compare> pq(nums.begin(),nums.begin() + k);for (int i = k; i < nums.size(); ++i) {// 堆中已经有k个元素if (nums[i] > pq.top()) {// 如果当前的数比堆顶大// 堆顶出堆,该数入堆pq.pop();//pq.push(nums[i]);pq.emplace(nums[i]);}}// 最后堆内一共k个元素// 堆顶即为第k大的元素return pq.top();}
};