旅行网格为回文

时间:2015-04-05 23:00:19

标签: c++ algorithm dynamic graph graph-algorithm

我一直在努力解决这个问题,并且除了天真的解决方案之外还没有能够提出任何其他问题。基本上,我给了一个大小为N的字符网格,我必须找到从左上角到右上角的不同路径的数量,当只向下行进到右边时给出回文。

以下是网格示例:

ABCD

BXZX

CDXB

WCBA

此网格中有12个回文,例如“ABXZXBA”。我的解决方案是遍历网格中的所有路径,并通过保留前N个字符的字符堆栈并为接下来的N个字符弹出每个字符并检查它们是否相同来检查该字符串是否是回文。当N变得太大而且我不确定如何继续时,此解决方案会超时。任何伪造的代码或建议将非常感激。

2 个答案:

答案 0 :(得分:1)

只是一个理论 - 我还没有试过编写代码:

您可以从左上角和右下角开始,并保持路径同步。因为它是一个回文,所以从底部到顶部的路径中需要有相同的字母。

每次查找路径中的下一步时,请检查反向步骤中是否存在匹配的字母。

反向步骤的可用路径可以进一步限制,因为它无法向前或向前移动。

当路径相遇时停止,这很复杂,因为它们可能最终位于相同的网格位置(奇数行),或者它们可能只是相遇(偶数行)。

后向跟踪和堆栈保持可能有点复杂,因为您必须考虑(可能)几个反向步骤的选择,但它应该减少可能性的数量。最好考虑它,因为前进和后退路径中的每一步都会为您提供一个新的(较小的)网格来检查回文。

答案 1 :(得分:0)

这样的东西?

(如果路径没有形成回文或超出边界/同步,至少会停止。)

JavaScript代码:

function f(m){

  var stack = [[0,0,m.length - 1,m.length - 1,""]],
      count = 0;

  while(stack.length > 0){

    var next = stack.pop(),
        y = next[0],
        x = next[1],
        yr = next[2]
        xr = next[3];

    if (y - yr > 0 || x - xr > 0){
      continue;
    } else if (m[y][x] != m[yr][xr]){
      continue;
    } else if (y == yr && x == xr){
      count++;
    } else {
      stack.push([y + 1,x,yr - 1,xr]);
      stack.push([y + 1,x,yr,xr - 1]);
      stack.push([y,x + 1,yr - 1,xr]);
      stack.push([y,x + 1,yr,xr - 1]);
    }
  }

  return count;
}

输出:

var t = [["A","B","C","D"]
        ,["B","X","Z","X"]
        ,["C","D","X","B"]
        ,["W","C","B","A"]];

console.log(f(t));

12