检查是否可以通过杂志文章中删除的一组字符创建给定的字符串

时间:2011-05-26 08:01:12

标签: algorithm dynamic-programming

“观察当你从杂志中剪切一个角色时,页面背面的角色也会被移除。给出一个算法来确定你是否可以通过粘贴来自给定杂志的剪切来生成给定的字符串。您将获得一个函数,该函数将识别字符及其在页面反面的位置,以用于任何给定的字符位置。“

我该怎么做?

我可以进行一些初步修剪,这样如果一个需要的角色只有一种方法可以被拾取,那么它最初是在转动动态技术的子问题之前采取的,但是在这个初始修剪之后是什么?

时间和空间的复杂性是什么?

3 个答案:

答案 0 :(得分:26)

正如@LiKao建议的那样,这可以使用max flow来解决。为了构建网络,我们制作两个顶点“层”:一个包含输入字符串中的所有不同字符,另一个包含页面上的每个位置。如果该位置在一侧具有该字符,则从字符到位置创建容量为1的边缘。使容量1的边缘从每个位置到接收器,并使从源到每个字符的边缘的容量等于输入字符串中该字符的多重性。

例如,假设我们在有四个位置的页面上搜索“FOO”这个词:

pos    1 2 3 4
front  F C O Z
back   O O K Z

然后我们生成以下网络,忽略位置4,因为它不提供任何必需的字符。

the generated network

现在,我们只需确定是否存在从length("FOO") = 3或更多的源到接收器的流量。

答案 1 :(得分:0)

您可以直接使用动态编程。

我们给n个字母的字符串s。我们给出了一组P = {p_1,...,p_k}。每件作品在前面有一个字母p_i.f,后面有一个字母p_i.b。

如果可以使用p \ subseteq P中的片段创建子串s_1 ... s_j,则使用f(j,p)表示返回true的函数,否则返回false。

以下重复出现: f(n,P)= f(n-1,P-p_1)| f(n-1,P-p_2)| ...... | f(n-1,P-p_k)

简单地说,使用P中所有部分的s的可行性取决于子串s_1 ... s_n-1的可行性给予少一块,我们尝试删除所有可能的部分(当然在实践中我们不必须逐个删除所有部分;我们只需删除那些p_i.f == s_n || p_i.b == s_n)的部分。

初始条件是f(1,P-p_1)= f(1,P-p2)= ... = true,假设我们已经检查了a-priori(线性时间)有足够的P中的字母用于覆盖s中的所有字母。

答案 2 :(得分:0)

尽管此问题可以公式化为最大流量问题(如已接受的答案所示),但将其公式化为二部图中的最大基数匹配问题更加简单有效。像Dinic's这样的Maxflow算法要比像Hopcroft–Karp algorithm这样的特殊情况算法要慢。

二部图是通过将给定字符串的每个字符的两个边缘添加到切口形成的,每边一个边缘。然后,我们运行Hopcroft–Karp。最后,我们只需检查匹配项的基数是否等于字符串的长度。

有关使用JGraphT的有效实施(在Scala中),请参阅我的GitHub

我想提出一种更有效的DP解决方案,因为Skiena的书在DP部分中存在此问题,但到目前为止还没有找到任何问题。