常用符号:$\Theta$表示渐近确界,O表示渐近上界,$\Omega$表示渐近下界;o表示非渐近上界,$\omega$表示非渐近下界。
下取整:$\lfloor\quad\rfloor$,上取整$\lceil\quad\rceil$
取模运算:a mod n = a - $\lfloor a/n \rfloor$*n
几个结论:$n^b=o(a^n)$(a>1),任何底大于1的指数函数比任何多项式函数增长的更快;
$lg^bn=0(n^a)$(a>0),任意正的多项式函数都比多项式对数函数增长的快;
阶乘n!=$o(n^n)$,n!=$\omega(2^n)$,lg(n!)=$\Theta(nlgn)$;
多重对数函数:$lg^*n$即,lglglg..n(共*个lg),增长非常缓慢的函数;
斐波那契数,非递归计算存在估算公式,但是现代计算机无法应用。比较好的方法是利用矩阵乘法做平方递归运算。
\[ \begin{bmatrix}F_{n+1} & F_n\\ F_n & F_{n-1}\end{bmatrix}=\begin{bmatrix}1 & 1\\1 & 0 \end{bmatrix} ^{\quad n}\]
递归式求解方法总结:
代换法(substituted method),代换法主要用于证明而非求解。代换法的技巧,其一是如果最后常数项无法消除,考虑更紧凑的假设上界;其二是某些变量的形式不好代换求解,可以考虑换元。
递归树法(recursion tree),通用方法,最重要的分析方法。
主方法(master method),适用于T(n)=a(T/b)+f(n)形式的递归式,分为三种情况,分别是
f(n)多项式大于、小于$n^{log_ba}$,或者二者渐近相等。主方法的证明来自递归树法。
附录部分:
附录A主要是一些常用的求和公式,在计算递归树的累加和时会用到这一部分的内容。比较常用的有:
几何级数:即等比数列。极限公式是$lim_{n=0}^{+\infty}a_n=\frac{a_0}{1-q}$,求和公式可用错位相减法推出;
等差数列:这个最简单,从略。
平方和公式:$\Sigma_{k=0}^nk^2=\frac{n(n+1)(2n+1)}{6}$
立方和公式:$\Sigma_{k=0}^nk^3=\frac{n^2(n+1)^2}{4}$
我记得高中的时候应该是背过这两个公式的,不过如今早已忘掉…
调和级数:$H_n=1+1/2+1/3+\cdots+1/n=lnn+O(1)$
下面介绍了一些求级数上下界的技巧,包括逐项微分、逐项积分、分割求和等。
利用积分求界:$\int_{m-1}^nf(x)dx \le \sigma_{k=m}^nf(k) \le \int_m^{n+1}f(x)dx$
前提是f(x)单调递增,这个不等式的成立是很显然的,只要联系到积分的几何意义。
附录B主要介绍了一些离散数学结构,包括集合、关系、函数、图和数的基本知识。
集合、函数部分从略。
关系:aRa,则R是自反的;如果aRb,bRc则aRc,则R是传递的;如果aRb则bRa,则R是对称的;如果aRb且bRa则a=b,则R是反对称的;
如果R是自反、对称和传递的,则R是等价关系;
如果R是自反、反对称和传递的,则R是偏序关系。
如果集合A中每对元素都满足关系R,则称R在A上是全序的或线性序的。
图:有向图G=(V,E),V代表顶点集,E代表边集,有向图中,自身环是可能的;无向图与有向图类似,但是边是由顶点对构成,不区分方向,并且不存在自身环。
两顶点之间有边,则称两顶点相邻。
顶点相关联的边的数目,称为顶点的度。有向图的度由入度+出度构成,并且自身环既算是入度也算是出度。
如果两顶点之间存在联通的边,则称之为路径,如果路径上各顶点均不重复,称之为简单路径。
在有向图中,如果两顶点之间可达,且路径至少包含一条边,则称路径形成回路,如果回路中顶点各不相同,则称为简单回路。
不存在自身环的有向图称为简单图,不存在回路的图称为无回路图。
如果无向图每对顶点之间都有路径连接,则称为连通图。
如果有向图的每对顶点之间都相互可达,则称其为强连通图。
无向图和有向图之间相互转换,无向→有向,需要将每条边用两条有向边代替;有向→无向,需要去掉自身环,并合并顶点对之间的边。
每对顶点都邻接的无向图称为完全图,如果无向图的顶点集可以划分为两个集合$V_1$和$V_2$,使得所有的边都位于两个集合之间,则称为二分图。
无回路的无向图称为森林,连通的、无回路的无向图称为自由树。
树:树分为很多种,自由树的定义见上条。
有根树:最常见的树,有根结点。定义叶结点、内部结点、兄弟结点、父结点、子女结点、树深度。
有序数是子女结点有序的有根树;二叉树是每个结点最多只有两个子女结点的树。
满二叉树的结点要么是叶结点要么是度为2的内部结点,其总结点数必定是$2^h-1$。
完全二叉树除了叶节点外,与满二叉树一一对应,完全二叉树的叶子结点中任意右结点必存在左兄弟。
problems
4-1 a-f可用主定理直接得出答案;
g 树为单线,深度为n,每一层都是n,故$\Theta(n^2)$
h 换元法,令n=$2^m$,则$T(2^m)=T(2^{m-1}+1$,即$T(x)=T(x/2)+1$,根据主公式T(x)=O(lgx),所以T(n)=O(lglgn)
4-2 数组A[1..N]内缺少了一个整数,数组A只能每次只能访问1bit的数据,如何在O(n)时间内找出缺失的整数。
有一个简单的思路,使用异或。因为异或本来就是位处理,所以在这里用这种处理方式仍然可行。设缺失的整数为x,令=1^2^3...^n,设缺少x,A中所有数据相互异或的结果为S',显然S=S'^x,S'^S=x,这样x就求出来了。换成按位来访问也是一样,不过循环的次数增加了常数倍而已。
不过这里的hint提示的方法其实是B[A[i]]=1,然后遍历B找到值为0的数,其序号就是缺失的整数。因此这里考虑使用统计的方法来解决这个问题,经过观察,可以得出以下结论:
A[i]的第x位($0 \le x\le m$)的和应该是$\lfloor \frac{n}{2^{x+1}} \rfloor \times 2^x + f(n \mod 2^{x+1}-2^x +1)$
\[ f(x)=\begin{cases}0& \text{$x<0$}\\x& \text{otherwise}\end{cases}\]
如果满足上述条件,则缺失的数是0,否则该位缺失1。
4-3 a>情况1)即为理想情况O(lgN);情况2)中每次访问一个元素需要复制整个数组,于是算法的复杂度为O(NlgN);情况3)每次访问一个元素需要复制整段数组(第i次访问的复杂度为$\Theta(N/2^i)$)一共需要访问lgN次,所以算法复杂度为O($N \times \Sigma_{i=1}^{lgN}\frac{i}{2^i}$=O(2N+lgN-2)=O(N)
b>情况1)仍然是O(NlgN);情况2)merge-sort部分的复杂度增加到O(NlgN),merge部分则增加到O($N^2$),所以总的复杂度(根据master method)为O($N^2)$;情况3)T(n)=2T(n/2)+$\Theta(n)$
4-4 a>$\Theta(n^{lg3})$
b>$\Theta(nlglgn)$
c>$\Theta(n^2 \sqrt{n})$
d>忽略常数,$\Theta(nlgn)$
e>$\Theta(nlglgn)$
f>$\Theta(n^{lg3})$
g>$\Theta(lgn)$
h,i>$\Theta(lgn!)$
j>$\Theta(nlglgn)$,用递归树展开,每层的代价都是n,树的高度为lglgn。