215. Kth Largest Element in an Array

来源:互联网 发布:最短查找时间优先算法 编辑:程序博客网 时间:2024/06/08 13:55

    • 题目描述
    • 题意理解
    • 分治法
      • 算法描述
      • 具体实现
      • 遇到的问题与改进方法
      • 复杂度
    • 其他方法
      • 利用标准库中的sort等


题目描述

Find the kth largest element in an unsorted array. Note that it is the kth largest element in the sorted order, not the kth distinct element.

For example,
Given [3,2,1,5,6,4] and k = 2, return 5.

Note:
You may assume k is always valid, 1 ≤ k ≤ array’s length.

题意理解

找出第k大的数

分治法

算法描述

1.选出数组中的任意一个数v,将比v小,比v大,等于v的数分别放smaller,larger,equal三个数组
2.判断:

  1. 如果k<=|larger|, 则说明第k大的数落在larger数组里面,递归找larger数组里面的第k大的数
  2. 如果|larger|<k<=|larger|+|equal|,则说明第k大的数落在equal数组里面,即主元素v就是要找的数,直接返回v
  3. 如果|larger|+|equal|<k,则说明第k大的数落在smaller数组里面,递归找smaller数组里面第k|larger|+|equal| 大的数(因为已经排除掉这么多个大数了,所以下一步的k要减去这个数的个数)

具体实现

class Solution {public:    int findKthLargest(vector<int>& nums, int k) {        vector<int> smaller, larger, equal;        return findKth(nums,smaller, larger, equal,k);    }    int findKth(vector<int> nums, vector<int>& smaller, vector<int>& larger, vector<int>& equal, int k) {        smaller.clear();        larger.clear();        equal.clear();        int v = nums[nums.size()/2];        for (auto num : nums) {            if (num < v)                smaller.push_back(num);            else if (num == v)                equal.push_back(num);            else                larger.push_back(num);        }        if (k <= larger.size())            return findKth(larger,smaller, larger, equal, k);        else if (k <= larger.size() + equal.size())            return v;        else            return findKth(smaller, smaller, larger, equal, k - (larger.size() + equal.size()));       }};

遇到的问题与改进方法

1.第k小和第k大不同,将判别条件调整一下就好
2.一开始选择主元素v时选择了第一个数,后来遇到那种降序的数组就超过了内存,懒得用随机选择,选用了中间那个数作为主元素
3.想要节省内存,所以将大等小三个数组也按引用传递下去,结果由于每次都会清零,将nums也清零了,因为nums在上一层也许是大等小三个数组的引用,所以nums没有继续用按引用传递

复杂度

时间复杂度 O(nlogn)

其他方法

利用标准库中的sort等

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

排序后直接找到第k大的数,时间复杂度 O(nlogn)

class Solution {public:    int findKthLargest(vector<int>& nums, int k) {        priority_queue<int> pq(nums.begin(), nums.end());        for (int i = 0; i < k - 1; i++)            pq.pop();         return pq.top();    }}; 

利用priority_queue排序,pop掉k-1个大数之后的那个就是第k大的数