LeetCode#215 Kth Largest Element in an Array

来源:互联网 发布:视频格式转换器 mac 编辑:程序博客网 时间:2024/06/02 06:28

[Description]

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.

[My Answer]

class Solution {public: int findKthLargest(vector<int>& nums, int k) {    return find(0, nums.size()-1, nums, k); }private:    int find(int begin, int end, vector<int>& nums, int k) {        if (begin < end) {        int i = begin, j = end, x = nums[begin];          while (i < j)        {              while(i < j && nums[j]<= x) // 从右向左找第一个大于x的数                  j--;               if(i < j)                  nums[i++] = nums[j];              while(i < j && nums[i]> x) // 从左向右找第一个小于等于x的数                  i++;               if(i < j)                  nums[j--] = nums[i];          }          nums[i] = x;          if (i+1 > k) {            return find(begin, i-1, nums, k);        } else if (i+1 == k) {            return x;        } else {            return find(i+1, end, nums, k);        }        } else {            return nums[begin];        }    }};

这道题应用了分治法中的Selection算法。

找到第K大的数字,即每次随机选取一个数字记为v,遍历数组,将数组分成三部分,大于v,等于v和小于v。之后比较各部分的数组长度和k的关系,对相应的部分进行递归,直到找到第k大的数字。如图:


这个方法的复杂度也依赖于每次选中的那个随机数,若每次都选中最差的数字,复杂度会达到O(n^2)。假设随机选择的数字落在数组的1/4~3/4之间为好的选择,好的选择发生的概率是50%,则好的选择发生的期望次数为2次。在两次划分后,被搜索的数组将最多缩减到其原始大小的3/4,由此可得 由这个递推式,可以得到T(n) = O(n),比排序的O(nlogn)要好。


这个方法也可以看做是快速排序的优化,每进行一次划分后都丢弃一部分没用的数据再对剩下的部分进行划分。


在LeetCode上看到了和我算法相同但是代码比我好而且比我快的方法,也贴在下面,他消去了递归的部分,值得学习。

#include <cstdlib>class Solution {public:    int findKthLargest(vector<int>& nums, int k) {        vector<int> bigger, small, equal;        int length;        int pos;        int key;        int jugde;        while (1) {            length = nums.size();            pos = rand() % length;            key = nums[pos];            vector<int>::iterator i = nums.begin();            for (int num = 0; num < length; ++num) {                int now = *(i+num);                if (key == now) {                    equal.push_back(key);                } else if (key > now) {                    small.push_back(now);                } else {                    bigger.push_back(now);                }            }            jugde = k - bigger.size();            // in the equal or small            if (jugde > 0) {                jugde -= equal.size();                // in the small                if (jugde > 0) {                                        k = jugde;                    nums.swap(small);                } else {                    // in the equal                                        return equal[0];                }            } else {                // in the bigger                nums.swap(bigger);                            }            bigger.clear();            small.clear();            equal.clear();        }        return nums[0];    }};


原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 淘宝收款不发货怎么办 新品标签没了怎么办 商家签收不退款怎么办 微信号存在风险怎么办 建网站不会管理怎么办 淘宝代销厂家发错货卖家怎么办 来分期退货退款怎么办 淘宝售后不退货怎么办 手机淘宝不退货怎么办 淘宝店不肯退款怎么办 退货快递丢件怎么办 淘宝客服不退款怎么办 淘宝被拉进黑名单怎么办 被买家举报假货怎么办 淘宝店售假3次怎么办 支付宝被骗200怎么办 淘宝被同行投诉怎么办 淘宝同行恶意投诉怎么办 淘宝被恶意举报怎么办 买到假的gucci包怎么办 淘宝买家退假货怎么办 淘宝产品被投诉怎么办 淘宝店铺被盗了怎么办 淘宝卖家不给解决问题怎么办 淘宝直通车亏钱怎么办 买家一直不评论怎么办 买家不主动评论怎么办 淘宝店主不发货怎么办 收钱码黑了怎么办 花呗冻结了怎么办 花呗超时不还会怎么办? 余额宝金额不足怎么办 花呗无法开通怎么办 花呗不能开通怎么办 淘宝客服态度差怎么办 买家秀被盗用怎么办 被投诉盗用图片怎么办 照片被淘宝盗用怎么办 淘宝视频被盗用怎么办 不锈钢边太锋利怎么办 美缝剂弄到不锈钢门巴手上怎么办