问题描述:给定一系列数{a1,a2,...,an},这些数无序的,现在求第k大的数。

看到这个问题,首先想到的是先排序,然后直接输出第k大的数,于是得到啦基于排序的算法

算法一:

#include<iostream>
#include<algorithm>
using namespace std;
bool cmp(int a, int b){ return a > b; }
int main(){
int k;
int a[9] = { 6, 5, 9, 8, 2, 1, 7, 3, 4 };
cout << "Input k:";
cin >> k;
sort(a, a + 9, cmp);
cout << a[k - 1] << endl;
return 0;
}

算法耗时主要在排序上,于是这个算法复杂度是O(nlogn);

算法二:

算法二是基于分解的方法,问题求解的是第k大的数,若果我将这系列数全部排序肯定会做太多无用功,比如我只需找出第k大,我可以先找出1大,第2大....第k大,在结束,此时时间为O(kn),当k比较少时候算法复杂度为0(n),若当k是关于n的函数时候算法复杂度为O(n2),最好的情况是k=1和k=n,最坏的情况是k=n/2,O(n)=<f(n)<=O(n2/2);具体代码如下:

#include<iostream>
using namespace std;
#include<cmath>
#define m int(pow(-2,31)); /*将m赋值为最小的整数*/
int Find_Kth(int a[], int n, int k);
int main(){
int k;
int a[9] = { 6, 5, 9, 8, 2, 1, 7, 3, 4 };
cout << "Input k:";
while (cin >> k){
cout << Find_Kth(a, 9, k) << endl;
}
return 0;
}
int Find_Kth(int a[], int n, int k){
int i,j, redex=0, NewMax = a[0];
for (i = 0; i < k; i++){ /*每次采用打擂台方法找到本次最大值后赋值为m*/
for (i = 0; i < n; i++)
if (a[i]>NewMax){
NewMax = a[i];
redex = i;
}
a[redex] = m;
}
return NewMax;
}

算法二有局限性,复杂度取决于k值,下面还是采用基于分解的思想,我们需要的是求第k大的数,于是可以采用快速排序的思想,任意选择一个数key将这序列数分解为s1和s2两个序列,其中s1中的数全部小于key,而s2中的数全部大于或等于key(key是s2中的最小的数),设s1和s2中元素个数为|s1|和|s2|,如果k==|s2|,那摩说明第k大的数恰好为key,如果k<|s2|,那么问题转化为求|s2|中第k大的数,如果k>|s2|,那么问题转化为求s1中第k-|s2|大的数,这样所有的过程可以通过递归来实现,于是有啦算法三。

算法三:
#include<iostream>
using namespace std;
int Find_Kth(int *a,int left,int right,int k);
int main(){
int k;
int a[9] = {6,5,9,8,2,1,7,3,4};
cout << "Input k:";
cin >> k;
cout << Find_Kth(a, 0, 8, k) << endl; /*输出第k大的数*/
return 0;
}
int Find_Kth(int *a,int left,int right, int k){
int key = a[left]; /*设定关键值*/
int low = left,high=right;
while (high>low){ /*类似于快速排序*/
while (a[high] >= key&&high>low)
high--;
a[low] = a[high];
while (a[low] <= key&&high>low)
a[low++];
a[high] = a[low];
}/*循环跳出必定有high=low*/
a[low] = key;
int r = right - low + 1; /*右端元素个数*/
if (k== r)
return a[low]; //恰好a[low]为第k大值
else if (k < r)
return Find_Kth(a, low+1, right, k); //第k大的值在a[low]右边第k大值
else
return Find_Kth(a, left, low - 1, k - r); /*第k大值在a[low]右边序列的第r-k大的值*/
}

事实上,C++的STl早已经为我们提供啦函数nth_element,包含头文件#include<iostream>中.nth_element有四个参数,第一个和第三个为begin和end的地址,表示搜索范围是区间[begin,end)里面的数,第二个参数为找的第k个数的地址,第四个参数为cmp函数,函数可以看成 void element(int*begin,int*Nth,int*end,boo(*pdrf)(int a,int b));

#include<iostream>
#include<algorithm>
using namespace std;
bool cmp(int a, int b){
return a > b;
}
int main(){
int k;
int a[9] = { 6, 5, 9, 8, 2, 1, 7, 3, 4 };
cout << "Input k:";
while (cin >> k){
nth_element(a, a + k-1,a+9, cmp); //将第k大的数放在k-1位置
cout << a[k - 1] << endl;
}
return 0;
}

寻找数列中第k大的数算法分析的更多相关文章

  1. [经典算法题]寻找数组中第K大的数的方法总结

    [经典算法题]寻找数组中第K大的数的方法总结 责任编辑:admin 日期:2012-11-26   字体:[大 中 小] 打印复制链接我要评论   今天看算法分析是,看到一个这样的问题,就是在一堆数据 ...

  2. 求数列中第K大的数

    原创 利用到快速排序的思想,快速排序思想:https://www.cnblogs.com/chiweiming/p/9188984.html array代表存放数列的数组,K代表第K大的数,mid代表 ...

  3. 寻找数组中第K大的数

    给定一个数组A,要求找到数组A中第K大的数字.对于这个问题,解决方案有不少,此处我只给出三种: 方法1: 对数组A进行排序,然后遍历一遍就可以找到第K大的数字.该方法的时间复杂度为O(N*logN) ...

  4. 查找数组中第k大的数

    问题:  查找出一给定数组中第k大的数.例如[3,2,7,1,8,9,6,5,4],第1大的数是9,第2大的数是8-- 思考:1. 直接从大到小排序,排好序后,第k大的数就是arr[k-1]. 2. ...

  5. 找出整数中第k大的数

    一  问题描述: 找出 m 个整数中第 k(0<k<m+1)大的整数. 二  举例: 假设有 12 个整数:data[1, 4, -1, -4, 9, 8, 0, 3, -8, 11, 2 ...

  6. 找出N个无序数中第K大的数

    使用类似快速排序,执行一次快速排序后,每次只选择一部分继续执行快速排序,直到找到第K个大元素为止,此时这个元素在数组位置后面的元素即所求 时间复杂度: 1.若随机选取枢纽,线性期望时间O(N) 2.若 ...

  7. 乱序数组中第k大的数(顺序统计量)

    该问题是顺序统计量中十分经典的问题. 使用快排中的分区法,将第k大的数排序.若双向扫描分区加上三点中值法或绝对中值法,可以保证在 O(n) 时间里找出第k大的数. 补充:可以直接使用C++STL中的n ...

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

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

  9. 4. Median of Two Sorted Arrays *HARD* -- 查找两个排序数组的中位数(寻找两个排序数组中第k大的数)

    There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the median of the two ...

随机推荐

  1. MojoliciousLite: 实时的web框架 概述

    MojoliciousLite: 实时的web框架: SYNOPSIS 简介: # Automatically enables "strict", "warnings&q ...

  2. iphone5升级到iOS7时出现“This device isn't eligible for the requested build”错误

    因为工作的需要我需要把自己的手机升级到iOS7,安装苹果的升级顺序总是报This device isn't eligible for the requested build错误,搜索相关的文章我的错误 ...

  3. javascript第二课javascript规范

    1.javascript严格区分大小写 2.声明变量一律使用var 推断类型 3.每条语句后面加分号 4.字符串使用单引号 5.html代码使用双引号,js用单引号

  4. C++编程技术之 异常处理(上)

    增强错误恢复能力是提高代码健壮性的最有力途径之一 之所以平时编写代码的时候不愿意去写错误处理,主要是由于这项工作及其无聊并可能导致代码膨胀,导致的结果就是本来就比较复杂的程序变得更加复杂.当然了,前面 ...

  5. HTML之学习笔记(四)格式化标签和特殊字符

    html常用的格式化标签使用如下 <html> <head> <title></title> </head> <body > & ...

  6. js 模拟java 中 的map

    //js模拟map Map = { obj : {}, put : function(key , value){ this.obj[key] = value; }, get : function(ke ...

  7. BZOJ 2245: [SDOI2011]工作安排( 费用流 )

    费用流模板题..限制一下不同愤怒值的工作数就可以了. ------------------------------------------------------------------------- ...

  8. $()和getElementById()的区别

    jQuery的成功多归功于其强大的选择器. 然而,相信不少初学jQuery的同学都会遇到下面的问题. 在javascript下,我们可以根据getElementById()来获取页面元素.如下: va ...

  9. 关于Python网络爬虫实战笔记③

    Python网络爬虫实战笔记③如何下载韩寒博客文章 Python网络爬虫实战笔记③如何下载韩寒博客文章 target:下载全部的文章 1. 博客列表页面规则 也就是, http://blog.sina ...

  10. ue中替换行

    把替换的字符替换为^p 如:123,12,3,1, 在UE力把“,”替换未“^p”,就会替换为 1231231