我需要获取将数组分成小子数组的所有可能方式的数量。我们可以在垂直和水平方向上分割数组。我的算法效果很好,但时间复杂度太高。你能看一下如何改进它吗?
参数
nStart
- 子数组的第一行
nEnd
- 子数组的最后一行
mStart
, mEnd
- 用于第二维(列)。
check()
- 检查结束条件的函数
return
- 分割数组的不同方式的数量。我们在函数检查返回true
时进行分割。public static long divide(int nStart, int nEnd, int mStart, int mEnd) {
long result = 0;
for(int i = 1; i < nEnd - nStart; i++) {
if(check(nStart, nStart + i, mStart, mEnd) && check(nStart + i, nEnd, mStart, mEnd))
result += divide(nStart, nStart + i, mStart, mEnd) * divide(nStart + i, nEnd, mStart, mEnd);
}
for(int i = 1; i < mEnd - mStart; i++) {
if(check(nStart, nEnd, mStart, mStart + i) && check(nStart, nEnd, mStart + i, mEnd))
result += divide(nStart, nEnd, mStart, mStart + i) * divide(nStart, nEnd, mStart + i, mEnd);
}
return (result == 0 ? 1 : result) % 1000000000;
}
例子
输入
2 2
10
01
输出 2
输入
3 2
101
010
输出 5
我认为您需要了解如何使用check()
函数。 当下一个子数组仅具有1或仅具有0时,我们停止除法。 这是代码:
public static boolean check(int nStart, int nEnd, int mStart, int mEnd) {
if((nEnd - nStart) + (mEnd - mStart) == 2)
return false;
for(int i = mStart; i < mEnd; i++) {
for(int j = nStart; j < nEnd; j++) {
if(bar[i][j] != bar[mStart][nStart])
return true;
}
}
return false;
}
2x2
矩阵可以垂直和水平地分成4 choose 2 + 4 choose 3 + 4 choose 4 = 11
种不同的方式。 - גלעד ברקן