使用相同的原理,但爲了更簡單的問題。首先,我預先計算數組的每個列的累加和,即A [i] [j] + = A [i-1] [j]。然後,對於每一對開始/結束行(i1,i2),我將它們視爲單個數組B [j],這意味着B [j] = A [i2] [j] - A [i1 -1] [j]的。然後,我們需要找到具有精確總和的子陣列。由於數組僅由正數組成,因此我可以在O(n)中找到它。總的來說,這個算法是O(n^3)。
對於您所提供的價值,我能找到一些additionals陣列:
對於目標= 19:
Found between (0,0) and (1,1)
Found between (0,3) and (2,4)
Found between (0,2) and (4,2)
Found between (1,1) and (2,2)
Found between (1,2) and (2,4)
Found between (2,0) and (4,0)
Found between (3,3) and (4,5)
目標= 23:
Found between (0,2) and (1,3)
Found between (0,3) and (2,4)
Found between (2,0) and (3,2)
Found between (2,3) and (3,4)
Found between (3,1) and (4,4)
的代碼我使用:
public static void main(String[] args) {
int[][] A = {
{3, 4, 8, 9, 3},
{2, 10, 4, 2, 1},
{8, 1, 4, 8, 0},
{3, 5, 2, 12, 3},
{8, 1, 1, 2, 2},
};
int target = 19;
for (int i = 1; i < A.length; i++)
for (int j = 0; j < A[i].length; j++)
A[i][j] += A[i - 1][j];
for (int i1 = 0; i1 < A.length; i1++) {
for (int i2 = i1 + 1; i2 < A.length; i2++) {
int j1=0, j2=0, s=0;
while(j2<A[i1].length) {
while(s<target && j2<A[i1].length) {
s += A[i2][j2] - (i1 > 0 ? A[i1-1][j2] : 0);
j2++;
if (s==target)
System.out.println(String.format("Found between (%d,%d) and (%d,%d)", i1, j1, i2, j2-1));
}
while(s>=target) {
s -= A[i2][j1] - (i1 > 0 ? A[i1-1][j1] : 0);
j1++;
if (s==target)
System.out.println(String.format("Found between (%d,%d) and (%d,%d)", i1, j1, i2, j2));
}
}
}
}
}
只是爲了clar ify:你在找什麼合適的數組或每個可能的數組?而且子排列的維度或大小是否重要? – GameDroids 2013-03-18 00:21:59
其實我需要找出匹配的每一個可能的數組。而我只有一個約束,子陣列應該是二維的。結果應該不考慮單個行或單個列中的單個元素或一組元素。 – Pradep 2013-03-18 00:33:14
問題的典型大小如何?矩陣的典型尺寸是多少?總和是否有上限?這可能是有用的,因爲矩陣中的所有數字都是正數,這意味着矩形的維數乘積必須總小於總和。如果總和很小,尺寸不能太大。 – naitoon 2013-03-18 03:23:42