算法导论课后习题解析 第四章 上
4.1-1
返回只包含绝对值最小的元素的子数组。
4.1-2
1
2
3
4
5
6
7
8
9
10
11
|
Maximun-Subarray(A)
max = -infinity
for
i = 1 to A.length
sum = 0
for
j = i to A.length
sum = sum + A[i]
if
sum > max
max = sum
low = i
high = j
return
(low, high, max)
|
每次内循环都利用上次累加的结果,避免重复运算。外层循环执行n次,第i次外循环内层循环执行n-i+1次,所以总的时间复杂度为 Θ(n2) Θ(n2)。
4.1-3
这道题
n0
n0的结果因人而异,我这里的结果是
n0=63
n0=63。利用这种方法虽然可以改善总体的运行速度,但是不能够改变两种方法运行时间相同时输入规模的大小。
4.1-4
在算法的最后判断最大子数组的总和是否小于零,如果小于零则返回空子数组(empty subarray)。
4.1-5
算法的思想就是从前往后累加,如果当前子数组的累加和小于零,则意味着最大子数组(maximun subarray)肯定不包括该子数组,所以果断舍弃,重新开始累加。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
Maximun-Subarray(A)
max = 0, sum = 0, cur_low = 1
for
i = 1 to A.length
sum = sum + A[i]
if
sum > max
max = sum
low = cur_low
high = i
else
if
sum < 0
cur_low = i + 1
sum = 0
if
max > 0
return
(low, high, max)
return
NIL
|
4.2-1
突然发现这个算法算起来真够麻烦的。
4.2-2
伪码还是比实际代码简单得多的,不用考虑一些中间存储的问题。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
Strassen-Method(A, B)
n = A.rows
let C be a
new
m*n matrix
if
n == 1
c11 = a11 * b11
else
S1 = B12 - B22
S2 = A11 + A12
S3 = A21 + A22
S4 = B21 - B11
S5 = A11 + A22
S6 = B11 + B22
S7 = A12 - A22
S8 = B21 + B22
S9 = A11 - A21
S10 = B11 + B12
P1 = Strassen-Method(A11, S1)
P2 = Strassen-Method(S2, B22)
P3 = Strassen-Method(S3, B11)
P4 = Strassen-Method(A22, S4)
P5 = Strassen-Method(S5, S6)
P6 = Strassen-Method(S7, S8)
P7 = Strassen-Method(S9, S10)
C11 = P5 + P4 - P2 + P6
C12 = P1 + P2
C21 = P3 + P4
C22 = P5 + P1 - P3 - P7
return
C
|
4.2-3
如果分割矩阵的时候矩阵的行数或列数为奇数,那么就把一个全零行或列补在矩阵上。最坏的情况下,每次分割都需要补行和列,所以递推公式变为
4.2-4
利用这种方法的递推公式为
- 如果 log3k=2 ⇒ k=9 log3k=2 ⇒ k=9,那么满足第2种情况, T(n)=Θ(n2lgn)=o(nlg7) T(n)=Θ(n2lgn)=o(nlg7)
- 如果 log3k<2 ⇒ k<9 log3k<2 ⇒ k<9,那么满足第1种情况, T(n)=Θ(n2)=o(nlg7) T(n)=Θ(n2)=o(nlg7)
- 如果 log3k>2 ⇒ k>9 log3k>2 ⇒ k>9,那么满足第3种情况,这时 log3k<lg7⇒k<3lg7≈21 log3k<lg7⇒k<3lg7≈21
所以最大的k为21。
4.2-5
- 第一种情况下的复杂度递推公式为 T(n)=132464T(n/68)+Θ(n2) T(n)=132464T(n/68)+Θ(n2), log68132464≈2.79512849 log68132464≈2.79512849
- 第二种情况下的复杂度递推公式为 T(n)=143640T(n/70)+Θ(n2) T(n)=143640T(n/70)+Θ(n2), log70143640≈2.79512269 log70143640≈2.79512269
- 第二种情况下的复杂度递推公式为 T(n)=155424T(n/72)+Θ(n2) T(n)=155424T(n/72)+Θ(n2), log72155424≈2.79514739 log72155424≈2.79514739
所以三种情况都比Strassen的方法稍好,其中第二种方法最好。
4.2-6
分别将两个将矩阵拆分为k个
n×n
n×n矩阵,然后再利用Strassen方法计算n阶方阵乘法。
4.2-7
由于
(a+bi)(c+di)=(ac−bd)+(ad+bc)i
(a+bi)(c+di)=(ac−bd)+(ad+bc)i,需要4次乘法,为了节省一次乘法需要利用到之前计算的结果。可以发现
ad+bc=(a+b)(c+d)−ac−bd
ad+bc=(a+b)(c+d)−ac−bd,所以只需要计算3次乘法即可。
4.3-1
假定有
∀m<n,T(m)≤cm2
∀m<n,T(m)≤cm2,代入递推式可得
4.3-2
假定有
∀m<n,T(m)≤clgm
∀m<n,T(m)≤clgm,代入递推式可得
4.3-3
假定有
∀m<n,T(m)≥c(m+d)lg(m+d)
∀m<n,T(m)≥c(m+d)lg(m+d),代入递推式可得
4.3-4
假定有
∀m<n,T(m)≤cmlgm+d
∀m<n,T(m)≤cmlgm+d,代入递推式可得
4.3-5
归并排序(merge sort)的时间复杂度递推公式为
T(n)=2T(n/2)+n
T(n)=2T(n/2)+n,分别证明其上下界
假定有
∀m<n,T(m)≤cmlgm
∀m<n,T(m)≤cmlgm,代入递推式可得
4.3-6
类似于4.3-3,假定有
∀m<n,T(m)≤c(m−d)lg(m−d)
∀m<n,T(m)≤c(m−d)lg(m−d),代入递推式可得
4.3-7
假定有
∀m<n,T(m)≤cmlog34
∀m<n,T(m)≤cmlog34,代入递推式可得
4.3-8
这道题目有错误,递推式应该为
T(n)=4T(n/2)+n
T(n)=4T(n/2)+n
假定有
∀m<n,T(m)≤cm2
∀m<n,T(m)≤cm2,代入递推式可得
4.3-9
令
m=lgn
m=lgn,得到
T(2m)=3T(2m/2)+m
T(2m)=3T(2m/2)+m,再令
S(m)=T(2m)
S(m)=T(2m),得到
S(m)=3S(m/2)+m
S(m)=3S(m/2)+m,利用主方法(master method)可以求得
T(n)=T(2m)=S(m)=O(mlg3)=O((lgn)lg3)
T(n)=T(2m)=S(m)=O(mlg3)=O((lgn)lg3)。
4.4-1
第一层
n
n,第二层
3/2n
3/2n,第三层
9/4n
9/4n,共
lgn
lgn层,最底层有
3lgn=nlg3
3lgn=nlg3个子过程,可得总时间
4.4-2
总时间为
4.4-3
第一层
n
n,第二层
2n+4×2
2n+4×2,第三层
4n+42×(2+1)
4n+42×(2+1),共
lgn
lgn层,最底层有
4lgn=n2
4lgn=n2个子过程,总时间为
4.4-4
第i层总时间为
2i(n−i)
2i(n−i),共n层,总时间为
4.4-5
第一层
n
n,第二层
(3/2)n−1
(3/2)n−1,第三层
(9/4)n−3−1/2
(9/4)n−3−1/2,最长的路径n层,由于该递归树不是满的,所以总时间小于满递归树
4.4-6
第一层
cn
cn,第二层
cn
cn,最短路径为
log3n
log3n层,所以总时间大于
log3n
log3n层的递归树
4.4-7
第一层
n
n,第二层
2n−4≤4⌊n/2⌋≤2n
2n−4≤4⌊n/2⌋≤2n,最长
lgn
lgn层,最短
lgn−1
lgn−1层,所以总时间
4.4-8
每一层都是
cn
cn,层数为
n/a
n/a,所以
4.4-9
类似于4.4-7,每层都是
cn
cn,最多
logmin(1α,11−α)n
logmin(1α,11−α)n层,最少
logmax(1α,11−α)n
logmax(1α,11−α)n层,所以