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.

Credits:

Special thanks to @mithmatt for adding this problem and creating all test cases.

Hide Tags Divide and Conquer Heap

这道题仅仅想出了使用heap来求解的方法。没有想出怎样使用分治来求解。可是在Discuss上看到了一份关于使用分治法很具体的介绍,而且对于当中的切割部分给出了一个很简洁的代码。


解法一:使用最小堆

这道题既能够使用最小堆也能够使用最大堆来求解。先说使用最小堆的解法。

最小堆中最顶端的元素是堆中最小的,我们构建一个大小为k的最小堆,那么最顶端的元素就是第k大的数。

使用数组中的前k个数构成一个最小堆。那么堆顶元素就是第k大的数,然后从第k+1个数開始遍历数组,假设遍历的数组元素小于堆顶元素,舍弃掉。假设遍历的数组元素大于堆顶元素,将堆顶元素出堆,然后将大于堆顶元素的数组中的元素插入堆中,再次形成堆。这样遍历完数组堆顶元素就是第k大的元素。这样的解法是保证在遍历到数组的不论什么一个元素时堆顶元素都是到遍历到的元素为止的第k大的元素。

runtime:8ms

    int findKthLargest(vector<int>& nums, int k) {
make_heap(nums.begin(),nums.begin()+k,greater<int>());
for(int i=k;i<nums.size();i++)
{
int top=nums.front();
if(nums[i]>top)
{
pop_heap(nums.begin(),nums.begin()+k,greater<int>());
nums[k-1]=nums[i];
push_heap(nums.begin(),nums.begin()+k,greater<int>());
}
}
return nums.front();
}

解法二:使用最大堆

使用最大堆也能够求解。就是将整个数组中的元素构成一个最大堆,这时堆顶元素是最大的,连续将堆顶元素弹出k-1次后堆顶元素就是第k大的数了。

因为stl中默认构建的是最大堆。所以这样的解法可能会更直观一些。

runtime:8ms

    int findKthLargest(vector<int>& nums, int k) {
make_heap(nums.begin(), nums.end());
for (int i=1; i<k; i++){
pop_heap(nums.begin(), nums.end());
nums.pop_back();
}
return nums[0];
}

解法三:分治法

分治法没有想出来,可是在Discuss中看到了一篇很具体的解答。我将它翻译成了中文。

这样的解法是由高速排序发展起来的。

高速排序中,每一次迭代。我们须要选取一个关键元素pivot,然后将数组切割成三个部分:

  1. 小于关键元素pivot的元素
  2. 等于关键元素pivot的元素
  3. 大于关键元素pivot的元素

如今。以[3,2,1,5,4,6]这个数组为例来分析。

假定每次选取最左端的元素作为关键的元素pivot,这样的情况下,是3,然后我们使用3作为pivot将数组分成上面指定的3个部分,最后结果是[1,2,3,5,4,6]。如今3是第3个元素而且我们知道它也是第3小的元素。

因为上面的切割是将比pivot小的元素放在了pivot的左边,所以pivot当pivot在第k-1位置是是第k小的元素。因为这道题目须要寻找第k大的元素,我们能够改动一下切割过程将比pivot大的元素放在k的左边。

这样。切割完毕后数组变成了[5,6,4,3,1,2],如今3是第4大的元素,假设我们须要寻找第2大的元素。我们知道它是在3左边,假设我们须要第5大的元素,我们知道它是在3右边。

如今简单写出算法的流程:

  1. 初始化left为0。right为nums.size()-1
  2. 切割数组,假设pivot在第k-1位。返回pivot
  3. 假设pivot在k-1右边。更新right为pivot的位置值
  4. 否则更新left为pivot的位置值。

  5. 反复2的步骤

runtime:8ms

     int findKthLargest(vector<int>& nums, int k) {
int pivot=nums[0];
int left=0;
int right=nums.size()-1;
while(true)
{
int pos=partion(nums,left,right);
if(pos==k-1) return nums[pos];
if(pos<k-1) left=pos+1;
else right=pos-1;
} } int partion(vector<int> &nums,int begin,int end)
{
int left=begin+1;
int right=end;
while(left<=right)
{
if(nums[left]<nums[begin]&&nums[right]>nums[begin])
swap(nums[left],nums[right]);
if(nums[left]>=nums[begin]) left++;
if(nums[right]<=nums[begin]) right--;
}
swap(nums[begin],nums[right]);
return right;
}

LeetCode215:Kth Largest Element in an Array的更多相关文章

  1. Kth Largest Element in an Array

    Find K-th largest element in an array. Notice You can swap elements in the array Example In array [9 ...

  2. leetcode面试准备:Kth Largest Element in an Array

    leetcode面试准备:Kth Largest Element in an Array 1 题目 Find the kth largest element in an unsorted array. ...

  3. 【LeetCode】215. Kth Largest Element in an Array (2 solutions)

    Kth Largest Element in an Array Find the kth largest element in an unsorted array. Note that it is t ...

  4. 剑指offer 最小的k个数 、 leetcode 215. Kth Largest Element in an Array 、295. Find Median from Data Stream(剑指 数据流中位数)

    注意multiset的一个bug: multiset带一个参数的erase函数原型有两种.一是传递一个元素值,如上面例子代码中,这时候删除的是集合中所有值等于输入值的元素,并且返回删除的元素个数:另外 ...

  5. Leetcode 之 Kth Largest Element in an Array

    636.Kth Largest Element in an Array 1.Problem Find the kth largest element in an unsorted array. Not ...

  6. [Leetcode Week11]Kth Largest Element in an Array

    Kth Largest Element in an Array 题解 题目来源:https://leetcode.com/problems/kth-largest-element-in-an-arra ...

  7. Lettcode Kth Largest Element in an Array

    Lettcode Kth Largest Element in an Array 题意:在无序数组中,寻找第k大的数字,注意这里考虑是重复的. 一直只会简单的O(nlogn)的做法,听说这题有O(n) ...

  8. 网易2016 实习研发工程师 [编程题]寻找第K大 and leetcode 215. Kth Largest Element in an Array

    传送门 有一个整数数组,请你根据快速排序的思路,找出数组中第K大的数. 给定一个整数数组a,同时给定它的大小n和要找的K(K在1到n之间),请返回第K大的数,保证答案存在. 测试样例: [1,3,5, ...

  9. LN : leetcode 215 Kth Largest Element in an Array

    lc 215 Kth Largest Element in an Array 215 Kth Largest Element in an Array Find the kth largest elem ...

随机推荐

  1. ACM程序设计选修课——1031: Hungar的得分问题(二)(杨辉三角+二进制转换)

    1031: Hungar的得分问题(二) 时间限制: 1 Sec  内存限制: 64 MB 提交: 15  解决: 10 [提交][状态][讨论版] 题目描述 距离正式选秀时间越来越近了,今天Hung ...

  2. HDU-2768 Cat vs. Dog

    题意一开始是理解错的...结果就各种WA啦~ 对于两个观众,假如有某只宠物,一个人讨厌另一个人却喜欢,这两个人就是有矛盾的,连边. 最后求最小顶点覆盖.因为把这个覆盖点集去掉的话剩下的图中没有两个点是 ...

  3. BZOJ 3167 [Heoi2013]Sao ——树形DP

    BZOJ4824的强化版. 改变枚举的方案,使用前缀和进行DP优化. 然后复杂度就是$O(n^2)$了. #include <map> #include <cmath> #in ...

  4. bzoj 1572: [Usaco2009 Open]工作安排Job

    Description Farmer John 有太多的工作要做啊!!!!!!!!为了让农场高效运转,他必须靠他的工作赚钱,每项工作花一个单位时间. 他的工作日从0时刻开始,有1000000000个单 ...

  5. FZOJ Problem 2103 Bin & Jing in wonderland

                                                                                                        ...

  6. Nginx配置https双向认证

    1.      前期的准备工作: 安装openssl和nginx的https模块 cd ~/ mkdir ssl cd ssl mkdir demoCA cd demoCA mkdir newcert ...

  7. 线程间通过PostMessage通信

    1.查看TMS项目中的相关实例 ::PostMessage(hWnd, WM_USER_MSG_REFRESH_UI, (WPARAM)UMP_REFRESH_MEMBER_INFO, 0); 参考文 ...

  8. linux-3.2.36内核启动2-setup_arch中的内存初始化1(arm平台 分析高端内存和初始化memblock)【转】

    转自:http://blog.csdn.net/tommy_wxie/article/details/17093307 上一篇微博留下了这几个函数,现在我们来分析它们         sanity_c ...

  9. 编译 Android 版本的 Opus 音频编解码库的方法

    Opus 音频编解码库是 Speex 音频编解码库的下一代版本,从编解码性能以及质量上来讲都有了长足的进步.Opus 的编译非常简单,但是官方并未给出详细的 Android 版本编译指南,查找了大量资 ...

  10. Django REST framework 的TokenAuth认证及外键Serializer基本实现

    一,Models.py中,ForeignKey记得要有related_name属性,已实现关联对象反向引用. app_name = models.ForeignKey("cmdb.App&q ...