find_max_crossing_subarray(A, low, mid, high) left_sum = MIN sum = 0 # 从 mid 到 low 找左区间的最大和,下标 for i inrange(low, mid, -1) sum += A[i] ifsum > left_sum left_sum = sum max_left = i right_sum = MIN sum = 0 # 找右区间的最大和,下标 for i inrange(mid + 1, high) sum += A[i] ifsum > right_sum right_sum = sum max_right = i return (max_left, max_right, left_sum + right_sum)
square_matrix_multiply(A, B) n = A.rows C = [n][n] for i inrange(1, n) for j inrange(1, n) c[i][j] = 0 for k inrange(1, n) c[i][j] += a[i][k] * b[k][j] return C
而使用 Strassen 算法求矩阵乘法只用 O(n^2.81) 的时间复杂度。
一个简单的分治算法:
为了简单说明,当使用分治算法计算 C = A x B 时,假定三个矩阵均为 n x n 矩阵,其中 n 为 2 的幂。 做出这个假设是因为每个分解步骤中,n x n 矩阵都被划分为 4 个 n/2 x n/2 的子矩阵,假定 n 是 2 的幂,那么只要 n >= 2 即可保证子矩阵规模 n/2 为整数。
假定将 A、B 和 C 均分解为 4 个 n/2 x n/2 的子矩阵:
1 2 3 4 5 6 7 8 9 10 11 12
A = |A11, A12| B = |B11, B12| C = |C11, C12| |A21, A22| |B21, B22| |C21, C22|
因此可以将 C = A x B 改写成: |C11, C12| = |A11, A12| x |B11, B12| |C21, C22| |A21, A22| |B21, B22|
等价于: C11 = A11 x B11 + A12 x B21 C12 = A11 x B12 + A12 x B22 C21 = A21 x B11 + A22 x B21 C22 = A21 x B12 + A22 x B22
利用上面的等价公式,为我们可以直接设计一个递归的分治算法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
square_matrix_multiply_recursive(A, B) n = A.rows C = [n][n] if n == 1 c[1][1] = A[1][1] x B[1][1] else # 将 A、B 和 C 划分成子矩阵,然后递归计算 C[1][1] = square_matrix_multiply_recursive(A[1][1], B[1][1]) + square_matrix_multiply_recursive(A[1][2], B[2][1]) C[1][2] = square_matrix_multiply_recursive(A[1][1], B[1][2]) + square_matrix_multiply_recursive(A[1][2], B[2][2]) C[2][1] = square_matrix_multiply_recursive(A[2][1], B[1][1]) + square_matrix_multiply_recursive(A[2][2], B[2][1]) C[2][2] = square_matrix_multiply_recursive(A[2][1], B[1][2]) + square_matrix_multiply_recursive(A[2][2], B[2][2])