问题描述

把数列\((x_1,x_2,\cdots,x_n)\)变换顺序为\((x_{p(1)},x_{p(2)},\cdots,x_{p(n)})\),其中\(p\)是\(A=\{1,2,3,\cdots,n\}\)的一个排列,要求只使用\(O(1)\)的额外空间。例如,当数列为\((10,20,30,40)\),\(p\)为\((3,1,2,4)\)时得到的数列是\((30,10,20,40)\).

算法描述

对于映射\(p:A\rightarrow A\),它的含义是“排列后的数组每个元素从哪里来”。即:变换后,数组下标\(k\)处的数从变换前的下标\(p(k)\)处来。变换后下标为\(p(k)\)处的数从变换前下标为\(p(p(k))\)处的数来……因此我们可以把这条变换的链记为:

\[k\leftarrow p(k)\leftarrow p(p(k))\leftarrow \cdots
\]

每一个下标都在唯一的一个“圈”内(原文这里的用词为"cycle")。举个例子:

对于给定的一个排列:

\[p=(8,2,7,1,6,9,3,4,5)
\]

我们可以观察到这样的规律:

\[\left\{\begin{array}{l}p(1)=8,p(8)=4,p(4)=1\\p(2)=2\\p(3)=7,p(7)=3\\p(5)=6,p(6)=9,p(9)=5\end{array}\right.
\]

对于括号中的每一行。最后一个等式右侧的数在\(p\)映射下的像,等于第一个等式左侧\(p\)作用的原像。对于每一个这样的圈,我们都能用大小为\(O(1)\)的额外空间完成数字的交换。而这个交换我们从每个圈中的最小数开始做。

代码描述:
for (int j = 1;j <= n;j++) {
int k = p(j);//n
while (k > j) {//n+a
k = p (k);//a
}
if(k == j) {
int y = x[j],l = p[k];//b
while (l != j) {//b+c
x[k] = x[l];//c
k = l;//c
l = p(k);//c
}
x[k] = y;//b
}
}
/*
这里b是变换p中"圈"的个数,c+b=n
a的含义是:对于每个j,在j所在的圈中第一个不大于j的数k距离p(j)的距离之和
*/
最坏情况

最坏的情况如下

\[p=(2,3,\cdots,n,1)\\a=(n-1)+(n-2)+\cdots +0=\frac{n^2-n}{2}\\b=1
\]

此为\(a\)的最坏情况和\(b\)的最好情况。

\[p=(1,2,\cdots,n-1,n)\\a=0\\b=n
\]

此为\(a\)的最好情况和\(b\)的最坏情况。

b的平均值分析

对于上面引用的\(p\)的实例:

\[p=(8,2,7,1,6,9,3,4,5)
\]

把所有的圈按照下述规则排列

1.圈内最小的数排在第一

2.圈内最小的数较大的,排在前面

则以上的\(p\)将变为\((5,6,9)(3,7)(2)(1,8,4)\),设\(q=(5,6,9,3,7,2,1,8,4)\).则这样的\(p\)到\(q\)的变换构成了一个排列到排列的双射。

这样,我们就可以把求\(b\)的值转化为求\(\{1,2,\cdots,n\}\)中满足\(q(j)=\min\{q(i)|i\le i \le j \}\)的\(j\)的个数。使得满足这样条件的\(j\)的个数为\(k\)的\(n\)元排列数共有\(\left[\begin{array}{c}n\\k\end{array}\right]\)种。(第一类Stirling数)

所以:

\[\overline{b}=\frac{\sum_{i=1}^n\left[\begin{array}{c}n\\i\end{array}\right]\times i}{n!}=H_n=\ln n+O(1)
\]

(当\(n\)充分大时,\(O(1)\)的值收敛到欧拉常数)

\[\sigma^2=H_n-H_n^{(2)}
\]

其中

\[H_n=1+\frac{1}{2}+\frac{1}{3}+\cdots+\frac{1}{n}\\H_n^{(2)}=1^2+(\frac{1}{2})^2+(\frac{1}{3})^2+\cdots+(\frac{1}{n})^2
\]

a的平均值分析

\[p=(8,2,7,1,6,9,3,4,5)\\q=(5,6,9,3,7,2,1,8,4)\\
\]

我们定义如下函数

\[y(i,j)=\left\{\begin{array}{l}1,\quad q(i)<q(k),\exist k \in (i,j]\\0,\quad else\end{array}\right.
\]

\[a=\sum_{1\le i<j\le n}y(i,j)
\]

\[\overline{y(i,j)}=\frac1{j-i+1}\\\overline a =\sum_{1\leq i<j\leq n}\overline{y(i,j)}=\sum_{1\leq i<j\leq n}\frac1{j-i+1}=\sum_{2\leq r\leq n}\frac{n+1-r}r
\]

其中,\(r=j-i+1\)

由上式:

\[\begin{aligned}\overline a&=\sum_{2\leq r\leq n}\frac 1r- \sum_{2\leq r\leq n}1\\&=(n+1)(H_n-1)-(n-1)\\&=(n+1)H_n-2n\\&=n\ln n +O(n)\\&=O(n\log n)+O(n)\end{aligned}
\]

\[\sigma^2=2n^2-(n+1)^2H_n^{(2)}-(n+1)H_n+4n
\]

由上面计算的\(b\)的均值\(\overline b=\ln n +O(1)=O(\log n)\)

所以算法的平均时间复杂度是\(O(n\log n)\)

《Mathematical Analysis of Algorithms》中有关“就地排列”(In Situ Permutation)的算法分析的更多相关文章

  1. 《Mathematical Analysis of Algorithms》中有关“选择第t大的数”的算法分析

    开头废话 这个问题是Donald.E.Knuth在他发表的论文Mathematical Analysis of Algorithms中提到的,这里对他的算法分析过程给出了更详细的解释. 问题描述: 给 ...

  2. "Mathematical Analysis of Algorithms" 阅读心得

    "Mathematical Analysis of Algorithms" 阅读心得 "Mathematical Analysis of Algorithms" ...

  3. 算法分析 Analysis of Algorithms -------GeekforGeeker 翻译

    算法分析 Analysis of Algorithms 为什么要做性能分析?Why performance analysis? 在计算机领域有很多重要的因素我们要考虑 比如用户友好度,模块化, 安全性 ...

  4. 《Principles of Mathematical Analysis》-chaper1-实数系与复数系

    今天我们开始简单的介绍数学分析这门课程,参考教材是Walter Rudin著的<Principles of Mathematical Analysis> 对于一门新课你最开始可能会问的是: ...

  5. GridView控件中加自动排列序号

    GridView控件中加自动排列序号 为 Gridview 增加一个新的空白列,如下: <asp:BoundField  HeaderText="序号">    < ...

  6. 6.046 Design and Analysis of Algorithms

    课程信息 6.046 Design and Analysis of Algorithms

  7. Lecture notes of Mathematical analysis

    Lecture notes of Mathematical analysis Preliminary theory Teaching purpose: Mathematical analysis is ...

  8. 排列计数(permutation)

    排列计数(permutation) 题目描述 求有多少种长度为n的序列A,满足以下条件: 1) 1~n这n个数在序列中各出现了一次 2) 若第i个数A[i]的值为i,则称i是稳定的.序列恰好有m个数是 ...

  9. Analysis of Algorithms

    算法分析 Introduction 有各种原因要求我们分析算法,像预测算法性能,比较不同算法优劣等,其中很实际的一条原因是为了避免性能错误,要对自己算法的性能有个概念. 科学方法(scientific ...

随机推荐

  1. mysql插入数据报错一二

    上周selenium+phantomjs+python3简单爬取一个网站,往数据库写数据遇到以下两个问题,记录一下: 报错一:Data truncated for column 'update_tim ...

  2. [Statistics] Comparison of Three Correlation Coefficient: Pearson, Kendall, Spearman

    There are three popular metrics to measure the correlation between two random variables: Pearson's c ...

  3. SpringBoot图文教程11—从此不写mapper文件「SpringBoot集成MybatisPlus」

    有天上飞的概念,就要有落地的实现 概念十遍不如代码一遍,朋友,希望你把文中所有的代码案例都敲一遍 先赞后看,养成习惯 SpringBoot 图文教程系列文章目录 SpringBoot图文教程1「概念+ ...

  4. Hexo站点Next主题添加google adsense广告

    本文转载自: https://www.93bok.com 前言 无意之间看到了google adsense的广告,于是就想到给我的站点也弄一个,本来以为是很简单的事,参考了很多资料,终于是部署成功了, ...

  5. 使用web写UI, 使用js对接C++项目, 提高开发效率

    ppt资源下载地址https://www.slidestalk.com/s/webui_nodejs_cmdlrx

  6. qt creator源码全方面分析(3-3)

    目录 qtcreatordata.pri 定义stripStaticBase替换函数 设置自定义编译和安装 QMAKE_EXTRA_COMPILERS Adding Compilers 示例1 示例2 ...

  7. SpringBoot图文教程12—SpringData Jpa的基本使用

    有天上飞的概念,就要有落地的实现 概念十遍不如代码一遍,朋友,希望你把文中所有的代码案例都敲一遍 先赞后看,养成习惯 SpringBoot 图文教程系列文章目录 SpringBoot图文教程1「概念+ ...

  8. Navicat for MySQL12破解

    本文摘抄自:https://blog.csdn.net/zhangli0910/article/details/83785147,https://blog.csdn.net/mmake1994/art ...

  9. base64编码的图片在网页中显示

    <img @error="changeImgSrc(user)" :src="user.src" width="42" height= ...

  10. python opencv Sobel、Laplace、canny算子的边缘提取 以及参数解析

    前提:各种算子不完全区分好坏,但根据我实际操作分析得到,有的算子之间效果大相径庭,但有的也很相似,也就是各有各的用法,这里按 Sobel.Laplace.canny三种算子作比较,看其结果: 一.  ...