谷歌访谈:找到字符串之间的疯狂距离

yuv*_*uvi 10 string algorithm

谷歌采访时向我询问了这个问题.我能做到O(n*n)......我可以在更好的时间做到这一点.字符串只能由1和0组成.

定义:

X和Y是由0或1组成的字符串

D(X,Y) =从X和Y开始删除开头常见的东西.然后从两个字符串中添加剩余的长度.

例如

D(1111, 1000)=只有第一个字母是常见的.所以剩下的字符串是111&000.因此结果length("111")&length("000")= 3 + 3 = 6

D(101, 1100)=只有前两个字母是常见的.所以剩下的字符串是01&100.因此结果length("01")&length("100")= 2 + 3 = 5

非常明显的是,发现这样一个疯狂的距离将是线性的.O(M).

现在的问题是

给n输入,比如说

1111
1000
101
1100
Run Code Online (Sandbox Code Playgroud)

找出可能的最大疯狂距离.

n是输入字符串的数量.m是任何输入字符串的最大长度.

O(n 2*m)的解决方案非常简单.它能以更好的方式完成吗?我们假设m是固定的.我们能比O(n ^ 2)做得更好吗?

Dou*_*gal 21

将字符串放入树中,其中0表示向左移动,1表示向右移动.所以举个例子

1111
1000
101
1100
Run Code Online (Sandbox Code Playgroud)

会导致树像

        Root
             1
          0     1
         0 1*  0  1
        0*    0*    1*
Run Code Online (Sandbox Code Playgroud)

其中*表示元素在那里结束.明确地构建这棵树O(n m).

现在我们必须找到直径(两个节点之间的最长路径,这与"疯狂距离"相同).在那里呈现的优化算法命中树中的每个节点一次.最多有min(n m, 2^m)这样的节点.

所以如果n m < 2^m,那么算法就是O(n m).

如果n m > 2^m(并且我们必须重复输入),那么算法仍然O(n m)是第一步.

这也适用于具有通用字母表的字符串; 对于带k字母的字母表构建一个k单独的树,在这种情况下运行时仍然是O(nm)相同的推理,虽然它需要k多少内存.

  • 这是一个特里. (2认同)