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. HDU——2068RPG的错排(错排公式)

    RPG的错排 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Sub ...

  2. IBM DB2 控制中心等图形工具在 Windows 下的字体设置

    原文地址(直接看原文): http://loveseaside.iteye.com/blog/648941 [简介如下] IBM DB2 在版本 8.0 以上就提供了一个跨平台的基于 Java 的一套 ...

  3. poj 6243 Dogs and Cages

    Dogs and Cages Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)To ...

  4. GridView从行寻找到该控件,以及从该控件获知该行

    原文发布时间为:2008-08-01 -- 来源于本人的百度文章 [由搬家工具导入] GridView从行寻找到该控件: protected void Button3_Click(object sen ...

  5. AC日记——[SDOI2015]星际战争 洛谷 P3324

    题目描述 3333年,在银河系的某星球上,X军团和Y军团正在激烈地作战. 在战斗的某一阶段,Y军团一共派遣了N个巨型机器人进攻X军团的阵地,其中第i个巨型机器人的装甲值为Ai.当一个巨型机器人的装甲值 ...

  6. 转载:P2P技术原理及应用(1)

    转帖allen303allen的空间 作 者:金海 廖小飞 摘要:对等网络(P2P)有3种主要的组织结构:分布式哈希表(DHT)结构.树形结构.网状结构.P2P技术已 经延伸到几乎所有的网络应用领域, ...

  7. Windows7/8/10中无法识别USB设备的问题解决

    1.打开控制面板 [Win+X]->[控制面板] 2.打开设备管理器 首先将面板切换为[小图标] 3.右键卸载“大容量设备”或者“磁盘管理器”的驱动,再重新刷新安装上去

  8. memcachq队列安装

    memcacheq是集中的队列小软件,使用起来简单,便捷,高效. 下载 http://git.oschina.net/sgfoot/linux-tools/raw/master/memcacheq-0 ...

  9. openfire Android学习(一)----实现用户注册、登录、修改密码和注销等

    以前学习过用Scoket 建立聊天,简单的建立聊天是没问题的,但如果要实现多人复杂的聊天,后台服务器代码就比较复杂,对于我这新手来讲就比较难了.后来在网上看到用openfire做服务器,利用强大的Sm ...

  10. 【spring cloud】Feign使用填坑

    引用地址:https://blog.csdn.net/liuchuanhong1/article/details/54728681 问题一: 在前面的示例中,我们讲过 @RequestMapping( ...