算法打基础——顺序统计(找第k小数)
这次主要是讲如何在线性时间下找n个元素的未排序序列中第k小的数。当然如果\(k=1 or k=n\),即找最大最小
数,线性时间内遍历即可完成,当拓展到一般,如中位数时,相关算法就值得研究了。这里还要说明的是,排序解
决是一种平凡算法,但其复杂度是\(\Theta(nlogn)\)
这次内容的主要知识点有:1.随机化版本的分治法求解&分析 2.基于1的优化pivot选择的算法&分析
1.随机化版本的分治法求解与分析
首先,要明确的是现在我们要解决的问题是求解n元素序列的第k小数
这种方法的主要思想是:从序列中随机选一个数pivot,然后用类似于merge-sort的分割方法,将序列分成大于和小于pivot的两部分.
根据两边元素的数量,迭代的去求解,最终找到第k小元素. 下面给出伪代码:
RAND-SELECT(A, p, q, i) ⊳ith smallest ofA[p..q]
if p= q then returnA[p]
r←RAND-PARTITION(A, p, q) ⊳随机化分割子程序,返回处理完后pivot下标(分割见前面分治法)
k←r–p+ 1 ⊳k 是 A[r]这个元素在子序列A[p~q]中的位置
if i== k then return A[r]
if i< k
then return RAND-SELECT(A, p, r –1, i)
else return RAND-SELECT(A, r + 1, q, i –k)
这里给出一个实例:
对这种随机化版本的分割进行分析,如果我们每次比较幸运分类的话:
T(n)=T(9n/10)+Θ(n)
=Θ(n)
如果每次分类都是最差情况的话(即0:n-1 split)
T(n)=T(n-1)+Θ(n)
=Θ(n2) 这种情况下比排序找这种平凡情况还要差
更具体的我们要分析随机版本运行的期望时间,因为数学公式多,所以这个就写在我的算法笔记里面了
结果最终肯定是Θ(n)!
2.基于1的优化pivot选择的算法&分析
算法1是期望时间复杂度为O(n),那么存不存在最差情况都是O(n)的算法呢? 由算法1,我们可以思考,是
什么导致了算法1的最差情况:是糟糕的划分。那么只要我们能找到一个好的划分方法,再基于算法1,就能
得到最差情况也是线性的算法了。
这里给出的Select算法就是这样的一个神奇的算法,这里先给出伪代码然后在用实例说明:
SELECT(i, n)
1.Divide the n elements into groups of 5. Find the median of each 5-element group by rote.
2.Recursively SELECT the median xof the floor{n/5} group medians to be the pivot.
3.Partition around the pivot x. Let k= rank(x).
4 if i= k then return x
elseif i< k
then recursively SELECT the ith
smallest element in the lower part
else recursively SELECT the (i–k)th
smallest element in the upper part
注意这个算法的3、4步和前面的算法是一样的,因为这个算法的主要目的是通过第1,2步找到一个分割的pivot
所以我们也着重分析1,2步
第一步:首先将序列按照5个一组进行分组,多出来的就不用管了; 然后通过随意什么方法找到5个元素中位数
第二步:通过递归调用这个算法Select找到floor{n/5}个元素的中位数x,我们将这个数作为分割用的pivot
注意这里的箭头都是指向更小的数。然后我们来更具体的分析:
我们知道至少ceil{floor{n/5}/2}个中位数是不大于x的,那么必然有3floor{n/10}个值是不大于x的。同理,对称的也有那么多是不小于x的.
然后我们想让3floor{n/10}≥n/4, 当n≥50时是成立的。 也就是说这样分割一部分必然是≥4/n,即另一部分
小于等于3n/4. 就是说如果来处理的话不会超过T(3n/4)
然后我们来分析一下整个算法的复杂度:
step1 分割应该就是遍历过程Θ(n)
step2 递归解决n/5的问题 T(n/5)
step3 按照得到的pivot分割数组 Θ(n)
step4 递归解决分割的数组,最大不超过3n/4 T(3n/4)
故 T(n)=T(n/5)+T(3n/4)+Θ(n)
由替代法(其实就是n/5+3n/4=19/20n),可以得到这个算法是线性的。
下面自己写的给出随机化算法的代码,第二个太懒了。。。还没写。写完会加上的
/////////////////////////CLRS video lec6 随机化版本的找第k大数/////////////////////////////////////////////////
/// 运行时间的期望是O(n),最差情况O(n^2) ///////////////////////////////////////////////////// #include<iostream>
#include<cstdlib>
#include<ctime>
using namespace std; #define random(x)(rand()%x) void findkth(int* a,int s,int e,int k)
{
if(s>e) return;
if(s==e)
{
cout<<a[s]<<endl;
return;
}
int index=rand()%(e-s+);
int pivot = a[s+index],temp;
temp=a[s];a[s]=pivot;a[s+index]=temp;
// 下面这一段做partition的工作
int i=s,j;
for(j=s+;j<=e;j++)
{
if(a[j]<pivot)
{
temp=a[++i];
a[i]=a[j];
a[j]=temp;
}
}
temp=a[i];a[i]=pivot;a[s]=temp;
if(i==k)
{
cout<<pivot<<endl;
return;
}
else if(i<k)
{
findkth(a,i+,e,k);
}
else
{
findkth(a,s,i-,k);
}
} int main()
{
int a[];
int i,j,k,index;
srand(time());
for(i=;i<;i++)
{
a[i]=random();
cout<<a[i]<<" ";
}
cout<<endl;
while(){
cin>>k;
findkth(a,,-,k);
}
return ;
}
Rand_kth
算法打基础——顺序统计(找第k小数)的更多相关文章
- 算法导论-顺序统计-快速求第i小的元素
目录 1.问题的引出-求第i个顺序统计量 2.方法一:以期望线性时间做选择 3.方法二(改进):最坏情况线性时间的选择 4.完整测试代码(c++) 5.参考资料 内容 1.问题的引出-求第i个顺序统计 ...
- 主席树-指针实现-找第k小数
主席树,其实就是N颗线段树 只是他们公用了一部分节点(๑•̀ㅂ•́)و✧ 我大部分的代码是从一位大佬的那里看到的 我这个垃圾程序连Poj2104上的数据都过不了TLE so希望神犇能给我看看, 顺便给 ...
- 数组第K小数问题 及其对于 快排和堆排 的相关优化比较
题目描述 给定一个整数数组a[0,...,n-1],求数组中第k小数 输入描述 首先输入数组长度n和k,其中1<=n<=5000, 1<=k<=n 然后输出n个整形元素,每个数 ...
- LC T668笔记 & 有关二分查找、第K小数、BFPRT算法
LC T668笔记 [涉及知识:二分查找.第K小数.BFPRT算法] [以下内容仅为本人在做题学习中的所感所想,本人水平有限目前尚处学习阶段,如有错误及不妥之处还请各位大佬指正,请谅解,谢谢!] !! ...
- hihoCoder 1133 二分·二分查找之k小数(TOP K算法)
#1133 : 二分·二分查找之k小数 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 在上一回里我们知道Nettle在玩<艦これ>,Nettle的镇守府有很 ...
- 【COGS 1534】 [NEERC 2004]K小数 &&【COGS 930】 [河南省队2012] 找第k小的数 可持久化01Trie
板子题,只是记得负数加fix最方便 #include <cstdio> ,N=; namespace FIFO { <<],*S=B,*T=B; #define getc() ...
- [经典算法题]寻找数组中第K大的数的方法总结
[经典算法题]寻找数组中第K大的数的方法总结 责任编辑:admin 日期:2012-11-26 字体:[大 中 小] 打印复制链接我要评论 今天看算法分析是,看到一个这样的问题,就是在一堆数据 ...
- 算法系列:寻找最大的 K 个数
Copyright © 1900-2016, NORYES, All Rights Reserved. http://www.cnblogs.com/noryes/ 欢迎转载,请保留此版权声明. -- ...
- 2018.07.08 NOIP模拟 第K小数(二分)
第K小数 题目背景 SOURCE:NOIP2016-AHSDFZ T1 题目描述 有两个正整数数列,元素个数分别为 N 和 M .从两个数列中分别任取一个数相乘,这样一共可以得到 N*M 个数,询问这 ...
随机推荐
- 异步编程和线程的使用(.NET 4.5 )
C#:异步编程和线程的使用(.NET 4.5 ) 异步编程和线程处理是并发或并行编程非常重要的功能特征.为了实现异步编程,可使用线程也可以不用.将异步与线程同时讲,将有助于我们更好的理解它们的特征 ...
- bigdata_Hadoop jps出现process information unavailable提示解决办法
启动Hadoop之后,使用jps命令查看当前系统的java进程情况,显示: hduser@jack:/usr/local/hadoop$ jps 18470 SecondaryNameNode 190 ...
- 数据结构之Huffman树与最优二叉树
最近在翻炒一些关于树的知识,发现一个比较有意思的二叉树,huffman树,对应到离散数学中的一种名为最优二叉树的路径结构,而Huffman的主要作用,最终可以归结到一种名为huffman编码的编码方式 ...
- Ajax得知(两)—— 一个简单的Ajax示例
通过部分博客认识Ajax之后,我们通过一个简单的实例来消化消化理论知识,一睹Ajax的庐山真面目. 1.实例功能: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZ ...
- LeetCode:same_tree题解
一. 题目: 给定两个二叉树,编写一个函数来检查它们是否相等或为空树.假设两个二叉树被觉得是相等的,那么它们在结构上是同样的,而且随意节点具有同样的值. 二. 分析 非常easy的题目 ...
- Microsoft dotnetConf 2015
Microsoft dotnetConf 2015 一些整理 dotnetConf 2015 直播计划: 第一天 (10 个主讲) - .NET Product Teams 主讲人为 .NET 产 ...
- jQuery基础---Ajax进阶
原文:jQuery基础---Ajax进阶 内容提纲: 1.加载请求 2.错误处理 3.请求全局事件 4.JSON 和 JSONP 5.jqXHR 对象 发文不易,转载请注明出处! 在 Ajax 基础一 ...
- sdut 3-4 长方形的周长和面积计算
3-4 长方形的周长和面积计算 Time Limit: 1000MS Memory limit: 65536K 标题叙述性说明 通过本题的练习能够掌握拷贝构造函数的定义和用法: 设计一个长方形类Rec ...
- mongodb操作之使用javaScript实现多表关联查询
一.数据控制 mongodb操作数据量控制,千万控制好,不要因为操作的数据量过多而导致失败. 演示一下发生此类错误的错误提示:
- 国内首篇介绍JanOS物联网操作系统的文章 - 如何把你的手机主板打造成物联网平台
天地会珠海分舵注:如无意外,您现在正在看的将是国内首篇且是唯一一篇介绍炙手可热的物联网的操作系统JanOS的文章!不信你去百度!希望大家能喜欢.但本文只是引言,更多信息请还是访问JanOS的官网:ht ...