确定序列是否是两个字符串重复的交错

时间:2016-05-15 21:46:22

标签: string algorithm time-complexity shuffle interleave

我有这个任务:

  

设x是一些有限和固定字母表上的字符串(想想英文字母)。特定   一个整数k我们使用x ^ k   表示通过连接x的k个副本获得的字符串。如果是x   是字符串HELLO然后x ^ 3   是字符串HELLOHELLOHELLO。重复x是   前缀x ^ k   对于某些整数k。因此,HELL和HELLOHELL都是重复的   你好。   两个字符串x和y的交织是通过改组重复获得的任何字符串   x的重复y。例如,HELwoLOHELLrldwOH是交错的   你好和世界。   描述一个算法,它将三个字符串x,y,z作为输入,并决定z是否为   交错x和y。

我只提出了一个具有指数复杂性的解决方案(我们有指向z字的指针,以及一种二叉树。在每个节点中,我都有可能的单词x和y的当前状态(在开始时都是空白的。)我正在处理z,并且节点有一个/两个/没有孩子,这取决于z中的下一个字符是否可以添加到x word,y word或no word。)我怎样才能变得更好比指数复杂性?

1 个答案:

答案 0 :(得分:2)

假设两个单词x和y的长度为N1和N2。

构造具有状态(n1,n2)的非确定性有限状态机,其中0 <= n1 <1。 N1和0 <= n2 < N2。所有州都在接受。

过渡是:

c: (n1, n2) --> ((n1 + 1) % N1, n2) if x[n1] == c
c: (n1, n2) --> (n1, (n1 + 1) % n2) if y[n2] == c

此NDFSM识别由交错重复x和y形成的字符串。

以下是实施NDFSM的一些方法:https://en.wikipedia.org/wiki/Nondeterministic_finite_automaton#Implementation

这是一个简单的Python实现。

def is_interleaved(x, y, z):
    states = set([(0, 0)])
    for c in z:
        ns = set()
        for i1, i2 in states:
            if c == x[i1]:
                ns.add(((i1+1)%len(x), i2))
            if c == y[i2]:
                ns.add((i1, (i2+1)%len(y)))
        states = ns
    return bool(states)

print is_interleaved('HELLO', 'world', 'HELwoLOHELLrldwOH')
print is_interleaved('HELLO', 'world', 'HELwoLOHELLrldwOHr')
print is_interleaved('aaab', 'aac', 'aaaabaacaab')

在最坏的情况下,它会在O(N1 * N2 * len(z))时间运行并使用O(N1 * N2)空间,但在很多情况下,时间复杂度将优于此除非字符串x和y是重复的。