逛别人博客的时候,偶然看到这一算法题,顺便用C++实现了一下。

最朴素的解法就是先对数组进行排序,返回第n个数即可。。

下面代码中用的是快速选择算法(不晓得这名字对不对)


 #include <vector>
#include <iostream>
#include <stdexcept>
#include <cstdio> const int QS_EERRMSG_LEN = ; /**
* 快速选择求无序数组中第n大的数字
* 因为select返回的是数组中对象的引用,
* 所以错误处理选择了异常
*/
template <typename T>
class QuickSelect
{
public:
typedef typename std::vector<T>::size_type size_type; /**
* 构造函数
* @brief QuickSelect
* @param array - vector类型的数组
*/
QuickSelect(std::vector<T>& array)
:m_array(array)
{} /**
* 选择第nth大的元素,
* 失败抛出std::out_of_range异常,
* 成功返回得到的元素
* @brief select
* @param nth
* @return
*/
const T&
select(size_type nth) throw(std::out_of_range)
{
//s_pos即第n大在排序之后数组中的下标
size_type s_pos = m_array.size() - nth; if(s_pos > m_array.size()){
char errmsg[QS_EERRMSG_LEN]; std::snprintf(errmsg, QS_EERRMSG_LEN, "Array access violation:{access:%ld range_length:%ld begin:%ld}.", nth, m_array.size(), );
std::out_of_range oor(errmsg);
throw oor;
} return this->select_pos(s_pos, , m_array.size());
} /**
* @brief select
* @param nth
* @param begin
* @param end
* @return
*/
const T&
select(size_type nth, size_type begin, size_type end) throw(std::out_of_range)
{
size_type array_size = m_array.size(); if(begin > array_size || end > array_size || end < begin){
char errmsg[QS_EERRMSG_LEN]; std::snprintf(errmsg, QS_EERRMSG_LEN, "The begin or end are not correct:{array_size:%ld begin:%ld end:%ld}.", array_size, begin, end);
std::out_of_range oor(errmsg);
throw oor;
} //要查找范围的长度
size_type range_length = end - begin + ; //要查找的第n大的元素在当前范围内的位置
size_type s_pos = range_length - nth; if(s_pos > range_length){
char errmsg[QS_EERRMSG_LEN]; std::snprintf(errmsg, QS_EERRMSG_LEN, "Array access violation:{access:%ld range_length:%ld begin:%ld}.", nth, range_length, begin);
std::out_of_range oor(errmsg);
throw oor;
}
else return this->select_pos(s_pos, begin, end);
}
private:
/**
* pos表示的是元素从begin开始的位置
* @brief select_pos
* @param pos
* @param begin
* @param end
* @return
*/
const T& select_pos(size_type pos, size_type begin, size_type end)
{
T& pivot = m_array[begin];
size_type swap_pos = begin; if(begin == end){
return m_array[pos];
} //进行一次快速排序
for(size_type i = begin + ;i < end;i ++){
if(m_array[i] < pivot){
std::swap(m_array[i], m_array[swap_pos ++]);
}
} //数组元素个数为奇数时多交换一次
if(m_array.size() % != ){
if(m_array[end - ] < pivot){
std::swap(m_array[end - ], m_array[swap_pos ++]);
}
} if(swap_pos - begin == pos){
return m_array[swap_pos];
}
else if(swap_pos - begin < pos){
return this->select_pos(pos, swap_pos + , end);
}
else{
return this->select_pos(pos, begin, swap_pos);
}
} /**
* @brief m_array
*/
std::vector<T>& m_array;
};


然后为了测试方便,实现vector输出,很简单的输出

 namespace std{

 template <typename T>
std::ostream& operator <<(std::ostream& out, const std::vector<T>& array)
{
for(auto e:array){
out << e <<" ";
}
out <<std::endl; return out;
} }

下面是测试用例

 int main()
{
std::vector<int> some{,,,,}; std::cout <<some; QuickSelect<int> qs(some); std::cout <<qs.select()<<std::endl; return ;
}

结果输出为

[root@localhost MYJOURNEY]# g++ quick_select.cpp -std=c++
[root@localhost MYJOURNEY]# ./a.out [root@localhost MYJOURNEY]#

求一无序数组中第n大的数字 - 快速选择算法的更多相关文章

  1. 无序数组中第Kth大的数

    题目:找出无序数组中第Kth大的数,如{63,45,33,21},第2大的数45. 输入: 第一行输入无序数组,第二行输入K值. 该是内推滴滴打车时(2017.8.26)的第二题,也是<剑指of ...

  2. [LeetCode] Kth Largest Element in an Array 数组中第k大的数字

    Find the kth largest element in an unsorted array. Note that it is the kth largest element in the so ...

  3. [LeetCode] 215. Kth Largest Element in an Array 数组中第k大的数字

    Find the kth largest element in an unsorted array. Note that it is the kth largest element in the so ...

  4. 前端算法题:找出数组中第k大的数字出现多少次

    题目:给定一个一维数组,如[1,2,4,4,3,5],找出数组中第k大的数字出现多少次. 例如:第2大的数是4,出现2次,最后输出 4,2 function getNum(arr, k){ // 数组 ...

  5. 无序数组中第K大的数

    1. 排序法 时间复杂度 O(nlogn) 2. 使用一个大小为K的数组arr保存前K个最大的元素 遍历原数组,遇到大于arr最小值的元素时候,使用插入排序方法,插入这个元素 时间复杂度,遍历是 O( ...

  6. 查找无序数组中第K大的数

    思路: 利用快速排序的划分思想 可以找出前k大数,然后不断划分 直到找到第K大元素 代码: #include <iostream> #include <algorithm> # ...

  7. 如何寻找无序数组中的第K大元素?

    如何寻找无序数组中的第K大元素? 有这样一个算法题:有一个无序数组,要求找出数组中的第K大元素.比如给定的无序数组如下所示: 如果k=6,也就是要寻找第6大的元素,很显然,数组中第一大元素是24,第二 ...

  8. SQL Server 2008 R2——查找最小nIndex,nIndex存在而nIndex+1不存在 求最小连续数组中的最大值

    =================================版权声明================================= 版权声明:原创文章 谢绝转载  请通过右侧公告中的“联系邮 ...

  9. 快速查找无序数组中的第K大数?

    1.题目分析: 查找无序数组中的第K大数,直观感觉便是先排好序再找到下标为K-1的元素,时间复杂度O(NlgN).在此,我们想探索是否存在时间复杂度 < O(NlgN),而且近似等于O(N)的高 ...

随机推荐

  1. 在mac中导入hadoop2.6.0源代码至eclipse

    一.环境准备 1.安装jdk.maven等 2.下载hadoop源代码,并解压 3.将tools.jar复制到Classes中,具体原因见http://wiki.apache.org/hadoop/H ...

  2. 2014-06-13 jq chart

    昨天接到上级说要在检测服务器上增加一个可以根据时间来查看服务器信息的线形图,那我首先就在原有的发送监控信息的功能上增加了把信息存入数据库中,然后再数据库中取得数据显示. 至于线形图的插件是jqx 的c ...

  3. symfony2 登录验证(转自http://www.newlifeclan.com/symfony/archives/300)

    注意:如果你需要为存储在某种数据库中的用户做一个登录表单,那么你应该考虑使用FOSUserBundle,这有助于你建立你的User对象,还为您提供了常见的登录.注册.忘记密码的路由和控制器. 在此文章 ...

  4. LeetCode_Longest Substring Without Repeating Characters

    Given a string, find the length of the longest substring without repeating characters. For example, ...

  5. Android 有缓存功能的请求封装接口

    /* * @Company 浙 江 鸿 程 计 算 机 系 统 有 限 公 司 * @URL http://www.zjhcsoft.com * @Address 杭州滨江区伟业路1号 * @Emai ...

  6. 福建省队集训被虐记——DAY1

    今天算是省冬的第一天--早上柯黑出题,说是"信心欢乐赛",其实是"使你失去信心.不再欢乐的比赛" 顺便orz一下来看这篇文章的各路神犇--求轻虐 水题 (py. ...

  7. 关于链表的一些重要操作(Important operations on a Linked List)

    上篇博文中讨论了链表的一些基本操作: 链表的基本操作(Basic Operations on a Linked List) 然而,为创建一个多功能的链表,在深度学习之前我们还需要了解更多的链表操作. ...

  8. Duff策略

    Tom Duff首先在C语言中提出了展开循环的构想,所以这种模式被称之为Duff策略.Duff策略背后的思想是每一次循环完成标准循环的1-8次.首先通过数组值得总数除以8来取定循环次数.Duff发现对 ...

  9. poj 3190 Stall Reservations 贪心 + 优先队列

    题意:给定N头奶牛,每头牛有固定的时间[a,b]让农夫去挤牛奶,农夫也只能在对应区间对指定奶牛进行挤奶, 求最少要多少个奶牛棚,使得在每个棚内的奶牛的挤奶时间不冲突. 思路:1.第一个想法就是贪心,对 ...

  10. copy模块

    # -*- coding: utf-8 -*- # python:2.x __author__ = 'Administrator' #copy复制对象 #作用:提供一些函数,可以使用潜复制和深复制进行 ...