給定一個 m × n 整數矩陣 matrix 和整數 target,回傳元素總和等於 target 的非空子矩陣的數目。
子矩陣是由矩陣中一些連續的行和列所定義的矩形區域。
範例:matrix = [[0,1,0],[1,1,1],[0,1,0]], target = 0
直接枚舉所有子矩陣有四個維度(上下行 r1,r2,左右列 c1,c2),時間 O(m²n²) 過慢。
降維策略:
colSum。總時間複雜度:O(m² × n)。
colSum[c](行 r1 到 r2、列 c 的和),預先建立每行的列前綴和 rowPrefix[r][c],使得 colSum[c] 可以 O(1) 計算。colSum[c]:固定 r1,每增加一行 r2 就把 matrix[r2][c] 加到 colSum[c],避免重複計算。colSum 使用前綴和 + HashMap:count[prefix_sum - target] 給出以當前位置結尾的合法子陣列數。O(m² × n),其中 m 為行數,n 為列數。
若 m >> n,可以轉置矩陣,時間變為 O(n² × m),取 min(m, n) 作為固定維度可以略微優化。
O(n),需要 colSum 陣列(長度 n)和 count HashMap(最多 n+1 個不同前綴和)。不計輸入矩陣本身。
1. For r1 from 0 to m-1:
a. Initialize colSum[0..n-1] = 0
b. For r2 from r1 to m-1:
i. For c from 0 to n-1: colSum[c] += matrix[r2][c]
ii. Initialize HashMap count = {0: 1}, prefSum = 0
iii. For c from 0 to n-1:
- prefSum += colSum[c]
- result += count[prefSum - target] (0 if not exists)
- count[prefSum] += 1
2. Return result枚舉所有 (r1, c1, r2, c2) 四元組,用二維前綴和 O(1) 計算子矩陣和,判斷是否等於 target。
對稱地,枚舉左列 c1 和右列 c2(O(n²) 組合),對每個組合計算「每行的列和」構成一維陣列,然後用 HashMap 求子陣列和等於 target 的個數(O(m))。總時間 O(n² × m)。
在行列方向都不均勻的情況下(如極端瘦長矩陣),可以自適應地選擇固定哪個維度,但這是工程優化,算法本質不變。
子矩陣和等於 target 的最小面積:在所有和等於 target 的子矩陣中,找面積最小的一個。在固定 r1, r2 後對 1D 陣列求最短子陣列和等於 target,但 1D 版本若含負數無法用滑窗,需用 HashMap + 排序前綴和,整體更複雜。
最大子矩陣和:不限制等於 target,找和最大的子矩陣。固定 r1, r2 後,對 colSum 陣列用 Kadane's Algorithm O(n) 求最大子陣列和,總時間 O(m² × n),是最大子矩陣和問題的標準解法。
推廣到三維張量:若問題推廣到三維(高 × 行 × 列),固定高度範圍(O(h²)),再固定行範圍(O(m²)),最後對 1D 陣列用 HashMap(O(n)),總時間 O(h²m²n)。維度每增加一層,複雜度就多一個平方因子,實際可行性急劇下降。