来自:【数据结构与算法分析——C语言描述】练习2.7

问题描述:假设需要生成前N个自然数的一个随机置换。例如,{4,1,2,5,2} 和 {3,1,4,2,5} 就是合法的置换,但 {5,4,1,2,1} 却不是,因为数1出现了两次而数 3 缺没有。这个程序常常用于模拟一些算法。我们假设存在一个随机数生成器 randInt(i, j) ,它以相同的概率生成 i 和 j 之间的一个整数。

下面是三个算法:

1.如下填入 A[0] 到 A[N-1] 的数组 A;为了填入 A[i] ,生成随机数直到它不同于已经生成的 A[0], A[1],  ... ,  A[i-1] 时,再将其填入 A[i] 。

2.同算法1,但是要保存一个附加的数组,称之为 Used(用过的)数组。当一个随机数 Ran 最初被放入数组A的时候,置Used[Ran]=1。这就是说,当用一个随机数填入 A[i] 时,可以用一步来测试是否该随机数已经被使用,而不是像第一个算法那样(可能)进行 i 步测试。

3.填写该数组使得 A[i] = i + 1。然后

for(i = 1; i < N; i++)
swap(&A[i], &A[randInt(0, i)]);

题目中有说“我们假设存在一个随机数RandInt(i, j)”,既然如此,暂时不必考虑其内部实现以及内存限制,只根据这个接口考虑算法即可。

算法1

i = 0;
while (i < N)
{
ran = randInt(0, N);
for (k = 0; k < i; k++)
{
if (A[k] == ran)
break;
}
if (k == i)
{
A[i] = ran;
count++;
}
}

以循环次数作为时间度量。循环从i=0到i=n-1写出n个不重复随机数,因为生成第i个不重复随机数的概率是(N-i)/N,所以理论上经过N/(N-i)次生成,得到不重复随机数的概率为1。所以总耗时为

这里做了分子的放大,以及这个调和和公式:

该算法的时间复杂度即为O(N2logN)。

算法2

i = 0;
while (i < N)
{
ran = randInt(0, N);
if (used[ran] == 0)
{
A[i] = ran;
used[ran] = 1;
i++;
}
}

算法 2 比算法 1 少了内层的 for 循环,所以时间复杂度降了一阶,即为 O(NlogN)。

算法3

for (i = 0; i < N; i++)
A[i] = i + 1;
for (i = 0; i < N; i++)
swap(&A[i], &A[randInt(0, i)]);

时间复杂度显然是线性级的,O(N)。

前N个自然数的随机置换的更多相关文章

  1. 生成前N个自然数随机置换的3个程序

    问题描述: 假设需要生成前N个自然数的一个随机置换.例如,{4,3,1,5,2}和{3,1,4,2,5}就是合法的置换,但{5,4,1,2,1}却不是,因为数1出现两次而数3却没有.这个程序常常用于模 ...

  2. 现有1~100 共一百个自然数,已随机放入一个有98个元素的数组a[98].要求写出一个尽量简单的方案找出没有被放入数组的那2个数,并在屏幕上打印这2个数

    void test7() { try { ]; ]; ]; ; ; int i; ; i < num.Length; i++) { num[i] = i + ; num1[i] = i + ;/ ...

  3. Python Random模块生成伪随机数字

    This module implements pseudo-random number generators for various distributions. 对于整数,有一个范围的均匀选择: 对 ...

  4. Redis之最大内存置换策略

    0.前言 Redis默认最大内存大小是应用程序可访问的内存大小, 32位windows下是2GB, linux下是3GB. 64位下可以访问的内存为2^64字节, Redis提供了maxmemory字 ...

  5. redis设置最大内存上限对置换策略的解读

    现在很少服务器还在使用32位的操作系统了,所以服务器的内存可以接近极限2^64的字节.redis配置文件中有限制最大内存的字段maxmemory,当redis的key达到最大值时,redis会有多种策 ...

  6. 从list中取N个随机生成一个集合

    在工作中发现有很多有序算法,较少见到一些可用的无序随机算法.无序随机算法的目的是让客户感觉每次都不一样,因为一直看一样的会审美疲劳哈. 在jdk自带一种CollectionUtils.shuffle& ...

  7. 《数据结构与算法分析:C语言描述_原书第二版》CH2算法分析_课后习题_部分解答

    对于一个初学者来说,作者的Solutions Manual把太多的细节留给了读者,这里尽自己的努力给出部分习题的详解: 不当之处,欢迎指正. 1.  按增长率排列下列函数:N,√2,N1.5,N2,N ...

  8. [Algorithm] 局部敏感哈希算法(Locality Sensitive Hashing)

    局部敏感哈希(Locality Sensitive Hashing,LSH)算法是我在前一段时间找工作时接触到的一种衡量文本相似度的算法.局部敏感哈希是近似最近邻搜索算法中最流行的一种,它有坚实的理论 ...

  9. 探索性思维——How to Solve It

    我觉得这篇文章和什么都能扯上点关系,比如编程. 很多人已经讨论过数学与编程的关系了,这里不想过多探讨,只是简单提一下:有些人把数学贬低地一文不值,认为做一般的应用软件用不到数学:而有些人则把数学拔高到 ...

随机推荐

  1. hdu 1829-A Bug's LIfe(简单带权并查集)

    题意:Bug有两种性别,异性之间才交往, 让你根据数据判断是否存在同性恋,输入有 t 组数据,每组数据给出bug数量n, 和关系数m, 以下m行给出相交往的一对Bug编号 a, b.只需要判断有没有, ...

  2. timer的使用

    ; private void timer1_Tick(object sender, EventArgs e) //定时执行事件 { button1.Text = i.ToString();//显示按钮 ...

  3. Winform——计算器进制转换

    namespace 进制转换2._0 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } p ...

  4. Qt之显示网络图片

    简述 Qt中包含了网络模块-network,我们可以很容易的进行各种网络编程和数据传输,关于network的类很多,其中包含:支持DNS.HTTP.TCP/UDP等众多高级类,可以参考助手. 下面我们 ...

  5. Quickhit快速击键

    一.项目分析 根据输入速率和正确率将玩家分为不同等级,级别越高,一次显示的字符数越多,玩家正确输入一次的得分也越高.如果玩家在规定时间内完成规定次数的输入,正确率达到规定要求,则玩家升级.玩家最高级别 ...

  6. HDU 1158 Employment Planning【DP】

    题意:给出n个月,雇佣一个人所需的钱hire,一个人工作一个月所需要的钱salary,解雇一个人所需要的钱fire,再给出这n个月每月1至少有num[i]个人完成工作,问完成整个工作所花费的最少的钱是 ...

  7. 转载:NPOI导出到Excel表格

    NPOI开发包下载:http://pan.baidu.com/share/link?shareid=4025220936&uk=2837994235 需要命名空间 using NPOI.HSS ...

  8. (转载)目前最细致清晰的NSDictionary以及NSMutableDictionary用法总结

    文章转载自:http://www.cnblogs.com/wengzilin/archive/2012/03/15/2397712.html 做过Java语言 或者 C语言 开发的朋友应该很清楚 关键 ...

  9. ProgressBar 各种样式

    多式样ProgressBar 普通圆形ProgressBar 该类型进度条也就是一个表示运转的过程,例如发送短信,连接网络等等,表示一个过程正在执行中. 一般只要在XML布局中定义就可以了. < ...

  10. 基于jQuery的AJAX和JSON的实例

    通过jQuery内置的AJAX功能,直接访问后台获得JSON格式的数据,然后通过jQuer把数据绑定到事先设计好的html模板上,直接在页面上显示. 我们先来看一下html模板:            ...