来自:【数据结构与算法分析——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. BZOJ 2228 礼物(gift)(最大子长方体)

    题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2228 题意:给出一个只含有NP两种字母的长方体.从中找出只含有字母N的长方体,造型为a* ...

  2. hibernate工具类HibernateUtil详解

    1.为什么要用hibernateUtil这个类,先看这段代码:     //加载配置文件信息默认为hiberna.cfg.xml,如果不是的话那么就在config()方法里面去解析他      Con ...

  3. Codeforces Round #206 div1 C

    CF的专业题解 : The problem was to find greatest d, such that ai ≥ d,  ai mod d ≤ k holds for each i. Let ...

  4. Android uiautomator gradle build system

    This will guide you through the steps to write your first uiautomator test using gradle as it build ...

  5. Cookie操作类 实现记住用户名和密码的功能

    import java.util.Hashtable;import java.util.Iterator;import java.util.Set;import javax.servlet.http. ...

  6. some resource favor

    http://www.moxiemanager.com/getit/ : picture file manage with blur 可以和Tinymce结合使用完美实现WYSIWYG的效果 http ...

  7. GUI for git|SourceTree|入门基础

    原文链接:http://www.jianshu.com/p/be9f0484af9d 目录 SourceTree简介 SourceTree基本使用 SourceTree&Git部分名词解释 相 ...

  8. duilib库分析: 消息流程分析

      转 看下CWindowWnd类与CPaintManagerUI类是咋进行消息分发的吧. 1. 先看下CPaintManagerUI类的MessageLoop函数: void CPaintManag ...

  9. BZOJ 1878 HH的项链

    不能分块(显然复杂度会炸啊.....) 离线+BIT.每个颜色在每个询问中只出现一次. #include<iostream> #include<cstdio> #include ...

  10. pageX, clientX ,screenX, offsetX, layerX, ,x的区别

    事件对象event的位置属性,这些参数比较容易混淆 1. pageX,pageY :IE不识别的,鼠标在页面上的位置,从页面左上角开始,即是以页面为参考点,不随滑动条移动而变化,其实就是clientY ...