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. Educational Codeforces Round 11——C. Hard Process(YY)

    C. Hard Process time limit per test 1 second memory limit per test 256 megabytes input standard inpu ...

  2. java面试题之为什么hashmap的数组初始化大小都是2的N次方?

    当数组长度为2的N次方时,不同的key算出的index相同的几率小,数据在数组上分配均匀,hash碰撞的几率小,提升查询效率,从大O(N)提升至O(1):

  3. GridControl 控制列中的控件显示

    一.需求描述 根据条件判断Checkbox的显示,先上个图,, 类似Demo中的这个,因为不能控制文本的显示,所以需对该列的其它事件做些处理,  二.解决方案 1.添加GridControl上需要的控 ...

  4. 【CF1017C】The Phone Number(构造)

    题意:要求构造一个1-n的排列,使得它的LIS+LDS最小 n<=1e5 思路:一个百度之星时候从LYY处听来的结论:1-n随机排列的LIS期望是根号级别的 考虑将LIS与LDS都构造成根号级别 ...

  5. HTML5 移动端头部标签

    <!DOCTYPE html> <!-- 使用 HTML5 doctype,不区分大小写 --> <html lang="zh-cmn-Hans"&g ...

  6. IDEA重新打jar包时报错MANIFEST.MF already exists in VFS

    报错原因:曾经打过jar包了,把之前的包删掉无用,VFS:虚拟文件系统.即使删掉之前的包,信息依然会在此处.故删掉MANIFEST文件夹,重新打包即可解决.

  7. linux下kill某个应用

    linux命令行与桌面切换快捷键Ctr+Alt+F1,Ctr+Alt+F7 ps -e | grep abc sudo kill xyz

  8. vue框架及其

    Vue常用UI框架 PC端: 1. ElementUI:http://element-cn.eleme.io/#/zh-CN 2. iView:https://www.iviewui.com/ 3. ...

  9. 【层次查询】Hierarchical Queries之亲兄弟间的排序(ORDER SIBLINGS BY)

    http://blog.itpub.net/519536/viewspace-624176 有关层次查询之前的文章参考如下. [层次查询]Hierarchical Queries之"树的遍历 ...

  10. python得到最长递增子串长度及起始位置【转】

    def incSeq(seq): start = 0 for i in xrange(1, len(seq)): if seq[i] < seq[i-1]: yield start, i - s ...