1. 知识梳理
- 最大子数组问题:
问题定义:找到并返回元素和最大的子数组的起止点以及最大值
方法:
①暴力法,见4.1-2( Θ ( n 2 ) \Theta(n^2) Θ(n2));
②分治法( o ( n 2 ) o(n^2) o(n2))//找寻跨左右子数组边界的最大子数组算法 FIND-MAX-CROSSING-SUBARRAY(A, low, mid, high) left-sum = -INF sum = 0 for i=mid downto low sum = sum + A[i] if sum > left-sum left-sum = sum max-left = i right-sum = -INF sum = 0 //reset for j=mid+1 to high sum = sum + A[j] if sum > right-sum right-sum = sum max-right = j return (max-left, max-right, left-sum + right-sum) //分而治之 FIND-MAX-SUBARRAY(A, low, high) if high == low return (low, high, A[low]) // base case: only one element mid = floor((low + high) / 2) (left-low, left-high, left-sum) = FIND-MAX-SUBARRAY(A, low, mid) (right-low, right-high, right-sum) = FIND-MAX-SUBARRAY(A, mid+1, high) (cross-low, cross-high, cross-sum) = FIND-MAX-CROSSING-SUBARRAY(A, low, mid, high) if left-sum >= right-sum and left-sum >= cross-sum return (left-low, left-high, left-sum) else if right-sum >= left-sum and right-sum >= cross-sum return (right-low, right-high, right-sum) else return (cross-low, cross-high, cross-sum)
- 矩阵乘法的Strassen算法
见习题4.2-2 - 递归式求解的三个方法
- 代入法:①猜渐近界(可借助递归树);②数学归纳法证明
- 递归树法:①层层展开,求树高和每层节点数目;②分别求叶节点代价和其余各层的代价,之后加起来即可。
- 主方法
令 a ≥ 1 , b > 1 a\ge1,b\gt1 a≥1,b>1是常数, f ( n ) f(n) f(n)是一个函数, T ( n ) T(n) T(n)是定义在非负整数上的递归式: T ( n ) = a T ( n / b ) + f ( n ) T(n) = aT(n/b) + f(n) T(n)=aT(n/b)+f(n),其中 n / b n/b n/b解释为 ⌊ n / b ⌋ \lfloor n/b \rfloor ⌊n/b⌋或 ⌈ n / b ⌉ \lceil n/b \rceil ⌈n/b⌉,那么 T ( n ) T(n) T(n)有如下渐近界:- 若对于某个常数 ε > 0 \varepsilon\gt0 ε>0有 f ( n ) = O ( n l o g b a − ε ) f(n) = O(n^{log_ba-\varepsilon}) f(n)=O(nlogba−ε),则 T ( n ) = Θ ( n l o g b a ) T(n) = \Theta(n^{log_ba}) T(n)=Θ(nlogba)。
- 若 f ( n ) = Θ ( n l o g b a ) f(n) = \Theta(n^{log_ba}) f(n)=Θ(nlogba),则 T ( n ) = Θ ( n l o g b a l g n ) T(n) = \Theta(n^{log_ba}lgn) T(n)=Θ(nlogbalgn)。
- 若对于某个常数 ε > 0 \varepsilon\gt0 ε>0有 f ( n ) = Ω ( n l o g b a + ε ) f(n) = \Omega(n^{log_ba+\varepsilon}) f(n)=Ω(nlogba+ε),且对于某个常数 c < 1 c<1 c<1和所有足够大的 n n n有 a f ( n / b ) ≤ c f ( n ) af(n/b) \le cf(n) af(n/b)≤cf(n),则 T ( n ) = Θ ( f ( n ) ) T(n) = \Theta(f(n)) T(n)=Θ(f(n))。
注:不是所有递归式都能用主定理解决,所有的大于小于都要是在多项式意义上的大于小于才可以用主定理。例如, T ( n ) = 2 T ( n / 2 ) + n l g n T(n) = 2T(n/2) + nlgn T(n)=2T(n/2)+nlgn就不能用主定理。
- *主方法证明
2. 课堂笔记
递归式求解方法的部分见《算法导论》Chapter3 Growth of Functions的课堂笔记。
3. 重点习题
练习题
4.1-2
BRUTE-FORCE(A)
n = A.length
max-sum = -INF
max-left = -1
max-right = -1
for i=1 to n
sum = 0
for j=i to n
sum = sum + A[j]
if sum > max-sum
max-sum = sum
max-left = i
max-right = j
return (max-left, max-right, max-sum)
4.2-2
STRASSEN-MATRIX-MULTIPLY(A, B)
n = A.rows
let C be a new nxn matrix
if n == 1
c11 = a11*b11
else partition A, B, and C
let each of S1, S2,..., S10 be a new n/2 x n/2 matrix
//规律:A, B 各有行相加(2)、主对角线相加(1)、列相减(2);
//注:B的第1列是下减上
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
let each of P1, P2, ..., P7 be a new n/2 x n/2 matrix
P1 = STRASSEN-MATRIX-MULTIPLY(A11, S1)
P2 = STRASSEN-MATRIX-MULTIPLY(S2, B22)
P3 = STRASSEN-MATRIX-MULTIPLY(S3, B11)
P4 = STRASSEN-MATRIX-MULTIPLY(A22, S4)
P5 = STRASSEN-MATRIX-MULTIPLY(S5, S6)
P6 = STRASSEN-MATRIX-MULTIPLY(S7, S8)
P7 = STRASSEN-MATRIX-MULTIPLY(S9, S10)
C11 = P5 + P4 - P2 + P6
C12 = P1 + P2
C21 = P3 + P4
C22 = P5 + P1 - P3 - P7
return C
4.2-7
COMPLEX-MULTIPLY(a, b, c, d)
A = (a+b)*(c+d)
B = a*c
C = b*d
return B-C + (A-B-C)i
待回顾的练习题
4.1-3、4.1-5
4.2-3、4.2-4、4.2-6
4.3-2 ~ 4.3-7、4.3-9
4.4-3
4.5-4、*4.5-5
4. 遗留的部分
- *4.6节 证明主定理
- 本章注记
- 习题4.4-4 ~ 4.4-9 以及 章末思考题(4-1 → \rightarrow → 4-6)