如何在矩阵中找到最大的回文平方

时间:2015-03-15 22:08:13

标签: algorithm language-agnostic dynamic-programming

我正在尝试解决一个问题,我给了一个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)。

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]colint[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直到找到结果