zoukankan      html  css  js  c++  java
  • LeetCode 数组中的第K个最大元素

    题目链接:https://leetcode-cn.com/problems/kth-largest-element-in-an-array/

    题目大意:

      变换一下题意就是求第 k 小。

    分析1:

      利用库函数 nth_element(a + l, a + k, a + r), 它会使 a 这个数组中区间 [l, r) 内的第 k 小的元素处在第 k 个位置上(相对位置),但是它并不保证其他元素有序! 

    代码如下(期望O(N)):

    1 class Solution {
    2 public:
    3     int findKthLargest(vector<int>& nums, int k) {
    4         k = nums.size() - k + 1;
    5         nth_element(nums.begin(), nums.begin() + k - 1, nums.end());
    6         return nums[k - 1];
    7     }
    8 };
    View Code

    分析2:

      用一个大小为 k 的大顶堆维护前 k 个元素.

    代码如下(O(Nlogk)):

     1 class Solution {
     2 public:
     3     int findKthLargest(vector<int>& nums, int k) {
     4         k = nums.size() - k + 1;
     5         priority_queue< int > topK;
     6         
     7         for(int i = 0; i < k; ++i) topK.push(nums[i]);
     8         for(int i = k; i < nums.size(); ++i) {
     9             if(nums[i] < topK.top()) {
    10                 topK.pop();
    11                 topK.push(nums[i]);
    12             }
    13         }
    14         
    15         return topK.top();
    16     }
    17 };
    View Code

    分析3:

      利用BFPRT算法.

    代码如下(最坏O(N)):

     1 class Solution {
     2 public:
     3     int findKthLargest(vector<int>& nums, int k) {
     4         return BFPRT(nums, nums.size() - k, 0, nums.size());
     5     }
     6     
     7     // 找[beg, end)的第k小,这里的k不是这个范围上的第k小,是整个数组的第k小
     8     int BFPRT(vector<int>& nums, int k, int beg, int end) {
     9         if(nums.size() == 1) return nums[k];
    10         vector<int> medians;
    11         int bestMid;
    12         int N = end - beg;
    13         
    14         // 每5个数一组求中位数
    15         for(int i = beg; i < end; i += 5) {
    16             if(i + 4 < end) medians.push_back(getMedian(nums, i, i + 5)); // 左闭右开
    17             else medians.push_back(getMedian(nums, i, end));
    18         }
    19         bestMid = getMedian(medians, 0, medians.size()); // 求中位数的中位数
    20         
    21         int lend, rbeg;
    22         partition(nums, beg, end, bestMid, lend, rbeg);
    23         
    24         if(k < lend) {
    25             return BFPRT(nums, k, beg, lend);
    26         }
    27         else if(k >= rbeg) {
    28             return BFPRT(nums, k, rbeg, end);
    29         }
    30         else {
    31             return bestMid;
    32         }
    33     }
    34     
    35     // 按照 mid 进行划分
    36     void partition(vector<int>& a, int beg, int end, int mid, int &lend, int &rbeg) {
    37         int l = beg - 1;
    38         int r = end;
    39         int p = beg;
    40         
    41         while(p < r) {
    42             if(p == l || a[p] == mid) ++p;
    43             else if(a[p] < mid) swap(a[p], a[++l]);
    44             else swap(a[p], a[--r]);
    45         }
    46         
    47         lend = l + 1;
    48         rbeg = r;
    49     }
    50     
    51     int getMedian(vector<int>& a, int beg, int end) {
    52         int mid = beg + ((end - beg) >> 1);
    53         if(end - beg > 5) return BFPRT(a, mid, beg, end);
    54         insertSort(a, beg, end); // 元素个数小于等于5个就用插入排序
    55         return a[mid];
    56     }
    57     
    58     void insertSort(vector<int>& a, int beg, int end) {
    59         for(int i = beg + 1; i < end; ++i) {
    60             for(int j = i; j > beg; --j) {
    61                 if(a[j] < a[j - 1]) swap(a[j], a[j - 1]);
    62                 else break;
    63             }
    64         }
    65     }
    66 };
    View Code
  • 相关阅读:
    dhl: ASP.NET MVC1.0 的图片(文件)上传功能
    一些不错的sql语句
    ASP.NET使用Memcached高缓存实例
    教你加快Win7 的启动速度
    写个VS2008使用单元测试NUnit的方法,希望对大家有帮助
    C#中ToString格式大全
    JQuery UI accordion学习笔记
    dhl:Sql表子查询
    windows 7 怎么在文件夹内开启图片预览功能
    教你如何将 优酷网等视频网站的视频外链时自动播放
  • 原文地址:https://www.cnblogs.com/zaq19970105/p/11466820.html
Copyright © 2011-2022 走看看