我正在尝试解决一个问题,我给了一个nXn方形字符矩阵,我想从中找出最大的回文平方的大小?最大的回文正方形是一个正方形,所有行和所有列都作为回文。
例如。 输入
a g h j k
s d g d j
s e f e n
a d g d h
r y d g s
输出将是:
3
对应中间正方形。我在考虑动态编程解决方案,但无法制定递归关系。我认为尺寸应该是(i,j,k),其中i,j是矩形的右下角,k是回文正方形的大小。 有人可以帮我解决这个问题的递归关系吗?
编辑:
n< 500,所以我相信我不能超越O(n ^ 3)。
答案 0 :(得分:3)
假设您可以解决以下问题:
(i, j)
结束是否有任何水平和垂直长度不同的回文。提示上述问题:
boolean[][][]palindrome;//Is there any palindrome ending at (i , j) has length k
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
palindrome[i][j][0] = true;
palindrome[i][j][1] = true;
for(int k = 2; k <= n; k++)
if(data[i][j - k + 1] == data[i][j] && palindrome[i][j - 1][k - 2])
palindrome[i][j][k] = true;
}
}
因此,我们可以创建两个三维数组int[n][n][n]col
和int[n][n][n]row
。
对于每个单元格(i,j),我们将计算长度为k的回文总数,结束于单元格(0,j),(1,j),...(i,j)和总数长度为k的回文,结束于格(i,0),(i,1),...(i,j)
for(int k = 1; k <= n; k++)
if(there is palindrome length k horizontally, end at cell (i, j))
row[i][j][k] = 1 + row[i - 1][j][k];
if(there is palindrome length k vertically, end at cell (i, j))
col[i][j][k] = 1 + col[i][j - 1][k];
最后,if row[i][j][k] >= k && col[i][j][k] >= k
- &gt;有一个方形回文长度k,以(i,j)结束。
总的来说,时间复杂度将是 O(n ^ 3)
答案 1 :(得分:0)
让我们从验证回文的复杂性开始:
可以在O(k)
中识别回文,其中k是回文的长度see here
然后,您需要为内部正方形中的每一行和每列进行一次2k次测试。 (使用回文k的长度,作为维度)
所以现在你有k * 2k -> O(2k^2) -> O(k^2)
然后你想将可能的搜索空间增加到整个数据集nxn
这是第二个变量被引入的时候
您需要在嵌套循环中迭代列1 to (n-k)
和所有行1 to (n-k)
。
所以现在你有(n-k)^2 * O(k^2) -> O(n^2 * k^2)
注意:此问题取决于多个变量
这与我建议你采用相同的方法来编写解决方案,从小做起并变得更大
答案 2 :(得分:0)
我确定可能有更好的方法,而且我非常确定我的逻辑是正确的,所以请将其视为未经测试的面值。
只是为了让这个例子很容易说我,j是左上角或坐标1,1
1 2 3 4 5 6 7 8
1 a b c d e f g f
2 d e f g h j k q
3 a b g d z f g f
4 a a a a a a a a
即(1,1) = a, (1,5) = e and (2,1) = d
现在不是通过检查每个第k列来检查您可以开始的每一列
即k=3
1)创建一个2D布尔数组,字符表的大小全部为TRUE
2)我首先检查不是回文的第3列cfg
,因此我不再需要测试第1列或第2列。
3)因为回文测试失败将2D数组(1,3)中的相应结果标记为FALSE(我知道不测试任何使用该位置的范围,因为它不是回文)
4)接下来检查第6列,fjf
这是一个回文,所以我回去测试第5列,ehz
!=回文
5)set(1,5)= FALSE
6)然后测试第8列,然后是7,
注意:您只需要测试8列中的5列。
因为一行中有k列是回文,现在测试相应的行。从本案例3的底行开始,因为如果失败,它将消除大多数其他检查
7)从(3,6)fgf
= palindrome
8)从(2,6)jkq
开始检查行!=回文
9)set(2,6)= FALSE
10)从(2,3)daa
!= palindrome
11)set(2,3)= FALSE
不需要再测试第2行,因为(2,3)和(2,6)都是假的
希望你能理解这一点。
注意:您可能会在k = n
处开始并递减k直到找到结果