算法导论课后习题探究(前五章:基础知识)
最近重读算法导论,这次准备要踏踏实实的学一下,包括课件、习题,都要搞定,于是决定开一个系列日志记录一下学习过程中的点滴,希望有兴趣的孩纸一块来探讨。今天是前几章,比较基础,权当热身。
2.2-2:这个题目本身没有意思,最坏复杂度和最佳复杂度都是$\theta(n^2)$。我感兴趣的是,这个算法如此之搓,以至于最佳复杂度也这么次么?
其实选择排序应该是指的一系列的需要选择最小元的排序算法。题目中这个是直接选择排序,其他此类经典的还包括堆排序和希尔排序,有兴趣的可以看下这篇文章:http://blog.csdn.net/touch_2011/article/details/6783965
当然了,直接插入排序也不是那么一无是处了,最典型的,它是稳定排序,上面那几位就不是。这在一些场合下,比如基数排序中,是很关键的。
现在我的疑惑是,这个排序难道不可以做一些非技术层面的修改,以改善一下其最佳复杂度么?所谓非技术层面的修改,指的是不引入新的数据结构(比如堆排序),也不引入新的算法(比如二分查找),仅仅是做一些小的处理(比如加哨兵什么的)。我思考的结果是没有好的办法,问了一些朋友也没有想法,大家谁有想法欢迎指教,感激不尽。
2.2-4:这个太抽象了,我表示2B青年搞不懂这么文艺的题啊!!但是这个题貌似能解决我上面困惑的样子啊,莫非作者也是这么想的?
2.3-7:先排序,接着枚举S中的一个元素i,二分查找S中是否含有元素x-i。
2-1:a).$k^2*(n/k)$; b).两两合并,并保持数组长度尽可能平衡;c).最大允许$k=\theta(lgn)$; d)取$[lgn]$即可。
2-4:d).归并排序的过程中计算逆序数。(很经典的算法,想当年本小白被这个算法震撼的不行)。
4.2-1:$n^{lg3}$,假设$T(n)\leq cn^{lg3}-dn$.
4.2-4:$\theta(n^2)$.
4.2-5:$\theta(nlgn)$(实际上是快排每次按$a:1-a$ 的比例分割的效率,MIT公开课还专门讲了这个情形)
4.4-1:$n_j=\lcell n/b^{j-1}\rcell$
4-1:a).$\theta(n^3)$; b).$\theta(n)$; c).$\theta(n^2lgn)$; d).$\theta(n^2)$; e).$\theta(n^{lg7})$; f).$\theta(\sqrt{n}lgn)$; g).$\theta(n^2)$; h). $\theta(lg lgn)$.
简要说明:倒数第二个实际上是朴素选择排序;最后一个,令$n=2^m$, $T(n)=T'(m)$, 则递归式转化为$T'(m)=T'(m/2)+1$, 由主定理,$T(n)=lgm=lg lgn$.
4-2: 这个题目比较有意思。以下是具体思路:
遍历$1..n$的第一位,将第一位是1和0的分开,分别存储于B1,B2;同样的处理A,存储于A1,A2;由于A比1..n少一个,则总存在一个数组$A_i$,其大小小于对应的$B_i$. 扔掉另一半,只保留$A_i$. 对$A_i$继续做同样的操作,直到数组长度为1. 其满足以下递归式:
$T(n)=T(n/2)+\theta(n)=\theta(n)$.
实际上,可以直接精确计算出操作次数:$T(n)=\sum_{i=0}^{lgn}{\frac{n}{2^i}}=2n$.
4-3: a). 三种策略的情况分别为:
1). $T(n)=T(n/2)+\theta(1)$------->$T(N)=\theta(lgN)$;
2). $T(n)=T(n/2)+\theta(N)$--->$T(N)=\theta(NlgN)$;
3). $T(n)=T(n/2)+\theta(n)$--->$T(N)=\theta(N)$;
4-4: a). $\theta(n^{lg3})$ b). $\theta(nlg lgn)$ c). $\theta(n^2\sqrt{n}$ d). $\theta(nlgn)$ e). 同b) f). $\theta(n)$ g). $\theta(lgn)$ h). $\theta(nlgn)$ i). $\theta(nlgn)$ j). $\theta(nlg lgn)$
简要说明:b),e)属于同一类,这个不太好猜,但是证明还是不太复杂的。
g).h) 直接迭代成求和式,利用积分放缩;
i) 做变量替换$n=2m$,可以转化为 h).
j) 直接画递归树,容易看到每层的代价为$n$, 树的高度参考 4-1-h, 最后用代换法证明之。
4.6: b)我们采取以下策略选择芯片:将芯片随机两两分组,不足两个的单独放置。然后将结组的分别做测试,依照测试结果,丢弃掉所有结果报告不是(good,good)的组,然后在结果报告是(good,good)的每组两个芯片中任意扔一个,留一个,若有单独的芯片则保留。
我们来证明,剩下的芯片依然满足“好芯片严格多于一半”的性质。我们只需要证明,操作过程中丢弃的坏芯片个数大于等于丢弃的好芯片个数。
事实上,操作可以看作分两步进行,一是丢弃所有结果不是(good,good)的组,一个在其余的组中随机选择。前者过程中,丢弃的坏芯片个数显然大于等于好芯片个数。
而对于后者,每组或者全是好芯片,或者全是坏的。由于原来的好芯片是严格多于坏芯片的,则全是好芯片的good组的个数不小于全是坏芯片的good组。(可以想到,这个条件无论是否有单独的芯片都是成立的),因此后一个操作丢弃掉的坏芯片同样不少于好芯片。证完。
P.S.: 这个问题本身还是不太好想的,不过题目中的$[n/2]$出卖了自己,给读者留下了线索。如果题目直接说$O(n)$,可能就不是那么容易想了。
c). 递归式为$T(n)=T(n/2)+\theta(n/2)$. $T(n)=\theta(n)$.
4-7. c). 若有反例,则考虑由两个最小值构成的矩形,其四个顶点就不满足Monge矩阵的条件了。
d). 很显然,要处理第$2i+1$行,只需要遍历$A[2i+1,f(2i)]$到$A[2i+1,f(2i+2)]$即可。因此一共需要遍历$\sum_{i}(f(2i+2)-f(2i)+1)=m+n/2$次。
e).$ T(m)=T(m/2)+O(n+m)$;$T(1)=\theta(n)$. 分析递归树可知,$T(m)=O(m+nlgm)$.
5.1-1:这个有点文字游戏的味道。主要问题在于,题目假设“总是能够”决定,即对于任意顺序都有结果,那很容易知道它们是有全序的。
5.1-2,5.1-3:这两个问题是同一类型的,我一开始想复杂了,后来想想题目要的可能就是如下简单粗暴的方法:
2. RANDOM(a,b)等价于RANDOM(0,k=b-a). 假设$2^{s-1}\leq k<2^{s}$, 则调用RANDOM(0,1) s 次,并将此s长二进制串转化为十进制数,若此数小于等于k, 则输出之,否则,丢弃之并重新执行一遍, 直到输出为止。
以下来分析期望运行时间:由于要丢弃的情况不超过1/2, 由几何概型模型知,期望时间$\leq 1/(1/2)*s=\theta(lg k)$.
3. 类似的,每次运行BIASED-RANDOM 两次,若结果为01,输出1;若结果为10,输出0;否则,重新执行两次,直到输出结果为止。其期望运行时间为 $1/2p(1-p)$.
5.2-1: 1/n;1/n!
5.2-2. $\sum_{k=1}^n \frac{1}{nk}$.
简要说明:恰好雇用两次相当于最大值不在第一位且第一位是最大值之前的所有元素中的最大值,假设第一位是$k$, 则此情形出现的概率为
$\frac{1}{n}\cdot \frac{1}{n-k}.$
其中$\frac{1}{n}$ 表示第一位是$k$的概率,而后一个分数表示$n$出现在所有的比$k$大的数的最前面的概率。
5.2-3:$7n/2$.
5.2-4: 答案是1.定义指示器变量$X_i=I\{\mbox{第i个顾客拿到了自己的帽子}\}$. 则容易知道$E[X_i]=Pr\{x_i=1\}=1/n$.
P.S. 即组合数学所研究的排列不动点问题。
5.2-5:$n(n-1)/4$, 指示器变量$X_{i,j}$表示$(i,j)$形成逆序对。
5.3-2:不能,因为不能生成所有需要的排列。
5.3-3: 概率不等,考虑$n=3$,即有反例。
5.3-4: 程序只能产生和原排列同属同一环排列的排列。
5.3-5: 利用$(1-a)(1-b)\geq 1-a-b$, 故有
$p=\prod_{i=0}^{n-1}(1-\frac{i}{n^3})\geq 1-\sum \frac{i}{n^3}=1-\frac{n-1}{2n}.$
5.3-6: 先按优先级进行排序,若有相等,则对于相等的元素重复调用程序,直到没有重复优先级为止。
5.4-2:这个解决的很不漂亮。。。。
考虑在投球第$i$次的时候第一次出现一个盒子包含两个球的情形,容易知道,其概率为$p_i=\frac{b*(b-1)\cdots (b-i+2)*(i-1)}{b^i}$, 然后利用期望的定义计算。(利用生成函数是可以计算其准确值的,过程太繁琐,这里略过)。
这个结果极其不漂亮,我尝试建立指示器变量去处理之,如下:
令$X_i=I\{\mbox{第i次投球之前所有盒子的球均小于2}\}$, 则显然投球次数$X=\sum_{i=1}^{b+1} X_i$, 而另一方面,
$E[X_i]=Pr\{X_i=1\}=\frac{b*(b-1)\cdots (b-i+2)}{b^{i-1}}.$
同样得到一个求和式,但是看起来和上面那个不一样,不知道是哪里出问题了,求高手指导。
5.4-3: 后者
5.4-4: 期望为$\frac{1}{{n^2}}{k\choose 3}$.
5.4-5: 和生日问题是等价的
5.4-6: 空盒子的期望数是$\frac{(n-1)^n}{n^{n-1}}$, 一个球的盒子的期望数是$\frac{{n-1}^{n-1}}{n^{n-2}}$.
5.4-7: 利用关系$1+x<e^x$.(P.S.题目中的lg 应为 ln).
5-1:这个题目没想明白,主要是对于条件概率的期望不太熟悉,参考了以下同学的思路,我没任何发展,就直接传送门了。
http://www.cnblogs.com/meteorgan/archive/2012/05/04/2482317.html
P.S.: 不利用条件概率的话,理论上是有问题的,行不通的。
5-2: 这个题仅仅是长,没什么营养,下面只说一下f).
定义指示器变量$X_i=I\{\mbox{第i个数之前没有出现过x}\}$, 则算法的期望运行次数$X=\sum_{i=0}^{n-k} X_i$, 而另一方面,
$E[X_i]=Pr\{X_i=1\}=\frac{{{n-k}\choose i}}{n\choose i}=\frac{1}{n\choose k}\sum_{i=0}^{n-k}{{n-i}\choose k}=\frac{{n+1}\choose {k+1}}{n\choose k}=\frac{n+1}{k+1}$.
P.S.: 结果如此之简洁,期待简洁的证明方法。