【问题标题】:Given a few strings, how many strings can be lexicographically least by modifying the alphabet?给定几个字符串,通过修改字母表可以按字典顺序最少有多少个字符串?
【发布时间】:2012-12-16 22:58:44
【问题描述】:

字符串的数量可以很大,如 30000。给定 N 个字符串,在修改英文字母后输出哪些字符串在字典上最少。例如acdbe……

例如,如果字符串是:

omm
moo
mom
ommnom

“妈妈”在字典上已经是原始英文字母表中最少的。我们可以通过在字母表中切换“m”和“o”(“abcdefghijklonmpqrstuvwxyz”)来最小化“omm”这个词。其他那些你不能按字典顺序首先,不管你做什么。

有什么快速的方法吗?我没有办法解决这个问题,除非尝试每一个可能的字母表

【问题讨论】:

  • 每个 unique 字符串都可以设为“字典顺序最少”。如果两个(或更多)字符串共享一个公共前缀,则其中只有一个可以按字典顺序设为最少。除非后缀以“新”字母开头。
  • 是的,我也注意到了。也符合这个想法,如果一个字符串是另一个字符串的子字符串,则更长的字符串不能是 lexi-least
  • 你的程序应该用上面的输入实际输出什么?
  • {"妈妈", "omm"}。我很确定它可以使用 wildplasser 的方法解决。

标签: algorithm alphabetical


【解决方案1】:

您希望能够说天气其中一个字符串(比如 s)可以变小。 您可以将其转化为检测图中循环的问题。方法如下:

考虑由 26 个顶点组成的图:V = { 'a', 'b', ..., 'z' } 假设 s 是最小的,并按顺序考虑 s 的字母,首先是第二个等等。

当您考虑第一个字母时,您知道对于所有其他字符串 x,s[0] 应该小于 x[0]。现在在图中为它们不是同一个字母的所有 x 添加一条从 s[0] 到 x[0] 的边。边缘的意思是“小于”。 现在考虑第二个字母,但只看那些与 s 具有相同第一个字母的字符串。做同样的事情 - 为这个归约集中的所有 y 添加一条从 s1 到 y1 的边。 然后移动到第三个字母,只考虑第一个和第二个字母相同的字符串..等等(你可以使用一个 Set 数据结构,它首先包含除 s 之外的所有字符串,你可以随时从中删除) .

现在,在您构建完图表后,您想知道是否存在循环。 事实上,如果有一个循环,这意味着这个 s 不可能是最小的,因为在循环之后,您必须使循环中的第一个字母小于它自己,这是不可能的。 另一方面,如果您没有循环,则该图是 DAG(有向无环图),并且任何 DAG 都可以进行拓扑排序,这意味着它的顶点(即字母表中的字母)可以按这样的顺序排序这样任何边缘都会从小到大。使用此顺序,由于图形的构造方式,您将拥有 s 最小的。

你可以看看detecting cycles in directed graphs - 这是一个很常见的问题,其复杂性是O(|V|+|E|)。在这种情况下 |V| = 26 和 |E|

因此复杂度为O(n)

如果您想检查每个字符串,您会得到O(n^2) 的整体复杂度。

【讨论】:

    猜你喜欢
    • 2010-11-13
    • 1970-01-01
    • 1970-01-01
    • 2018-04-25
    • 1970-01-01
    • 2019-11-03
    • 1970-01-01
    • 2014-08-05
    • 2012-02-29
    相关资源
    最近更新 更多