最少切换以创建交替链

时间:2012-09-16 10:38:55

标签: algorithm recursion dynamic-programming

我正试图在SPOJ上解决这个问题:http://www.spoj.pl/problems/EDIT/

我正在尝试对算法进行一次不错的递归描述,但是我失败了,因为我的想法一直在旋转!你能帮我解决这个问题吗?我将尝试描述我试图解决这个问题的方法。

基本上我想解决大小为j-i的问题,其中i是起始索引,j是结束索引。现在,应该有两个案例。如果j-i是偶数,那么起始和结束字母都必须是相同的情况,并且当j-i是奇数时它们必须是相反的情况。我也想减少较小尺寸(ji-1或ji-2)的问题,但我觉得如果我知道一个小问题的解决方案,那么构建一个更大问题的解决方案也应该考虑到开始和结束较小问题的字母案例。这正是我感到困惑的地方。你们能把我的想法放在正确的轨道上吗?

3 个答案:

答案 0 :(得分:3)

我认为递归并不是解决这个问题的最佳方法。如果我们采取不同的方法,它可以很快解决!

让我们考虑二进制字符串。假设大写字母 1 ,小写字母 0 。例如

AaAaB -> 10101
ABaa  -> 1100
a     -> 0

“正确”的交替链是 10101010 ..或 010101010 ..

我们将字符串之间的 Hamming distance 更改为另一个字符串所需的最小替换次数。我们必须找到的是输入二进制串与相同长度的两个交替链之一之间的最小汉明距离。

这并不困难:我们对每个字符串进行异或,然后计算1的数量。 (link)。例如,让我们考虑以下字符串: ABaa

  • 我们将其转换为二进制:

    ABaa - > 1100

  • 我们只生成两条长度为4的交替链:

    1010

    0101

  • 我们用输入XOR对它们进行异或:

    1100 XOR 1010 = 0101

    1100 XOR 0101 = 1010

  • 我们计算结果中的1并取最小值。在这种情况下,它是 2

我用Java编写了这个程序,进行了一些小的优化(缓冲的I / O,没有真正需要生成交替链)并且它被接受了:( 0.60秒一次)。

enter image description here

答案 1 :(得分:1)

给定长度为n的任何字符串,只有两个可能的“交替链”。 这2个变体可以通过设置第一个字母状态顺序定义(如果第一个是上部,则第二个是下部,第三个是上部......)。

一个简单的线性算法是对第一个字母做出两个简单的假设:

  1. 第一个字母是UpperCase
  2. 首字母是LowerCase
  3. 对于每个假设,运行一个简单的编辑距离算法,你就完成了。

答案 2 :(得分:1)

你可以递归地执行它,但是你需要在函数之间传递和返回大量的状态信息,我认为这个问题可以通过一个简单的循环来解决,这是不值得的。

正如其他人所说,有两种可能的"期望的结果"字符串:一个以大写字母开头(让我们称之为result_U),一个以小写字母(result_L)开头。我们想要较小的EditDistance(input,result_U)和EditDistance(input,result_L)。

另外要注意,要计算EditDistance(input,result_U),我们不需要生成result_U,我们只需要一次扫描输入1个字符,并且每个不符合预期情况的字符需要1个编辑到使其成为正确的情况,即将编辑距离加1。同上EditDistance(输入,result_L)。

此外,我们可以组合两个循环,以便我们只扫描输入一次。实际上,这可以在读取每个输入字符串时完成。 一个天真的方法看起来像这样:

伪代码:

EditDistance_U = 0
EditDistance_L = 0

Read a character
To arrive at result_U, does this character need editing?
  Yes => EditDistance_U += 1
  No  => Do nothing
To arrive at result_L, does this character need editing?
  Yes => EditDistance_L += 1
  No  => Do nothing
Loop until end of string
EditDistance = min(EditDistance_U, EditDistance_L)

对于上述内容也有明显的优化,但我会留给你。

提示1:我们在循环中真的需要2个条件吗?它们如何相互关联?

提示2:什么是EditDistance_U + EditDistance_L?