我什至不知道是否存在解决方案。这里是详细的问题。您是一个接受无限长字符流的程序(为简单起见,您可以假设字符是 1 或 0)。在任何时候,我都可以停止流(假设在 N 个字符通过之后)并询问您目前收到的字符串是否是回文。您如何使用更少的次线性空间和/或时间来做到这一点。
4 回答
是的。答案大约是下降了三分之二http://rjlipton.wordpress.com/2011/01/12/stringology-the-real-string-theory/
编辑:有些人要求我总结结果,以防链接失效。该链接提供了有关以下定理证明的一些细节:有一个多带图灵机可以实时识别初始非平凡回文。 (总结,也由链接的文章提供:假设机器已经读取了输入的x1,x2,...,xk。那么它只有恒定的时间来确定x1,x2,...,xk是否是回文.)
多磁带图灵机只是具有几个可以读取和写入的并排磁带的机器。在非常具体的意义上,它完全等同于标准的图灵机。
实时计算是图灵机必须每 M 步从输入中读取一个字符至少一次(对于某个有界常数 M)。很容易看出,任何实时算法都应该是线性时间的。
有一篇关于证明的论文大约 10 页,可在此处的机构付费墙后面找到,我不会在其他地方重新发布。如果您愿意,可以联系作者以获得更详细的说明;我最近才读到这篇文章,并意识到它或多或少是您正在寻找的。
您可以使用滚动散列或更多滚动散列以确保准确性。增量计算到目前为止读取的字符的哈希值,按照读取的顺序和相反的读取顺序。
x*3^(k-1)+x*3^(k-2)+...+x*3^0
例如,如果您的哈希函数是x
您读取的字符在哪里,那么您将这样做:
hLeftRight = 0
hRightLeft = 0
k = 0
repeat until there are numbers in the stream
x = stream.Get()
hLeftRight = 3*hLeftRight + x.Value
hRightLeft = hRightLeft + 3^k*x.Value
if (x.QueryPalindrome = true)
yield hLeftRight == hRightLeft
k = k + 1
显然,您必须计算哈希模数,可能是素数或二的幂。当然,这可能会导致误报。
第二轮
在我看来,每个新角色都有三种情况:
- 字符破坏了潜在的对称性,例如,aab -> aabc
- 字符向中间延伸,例如 aab -> aabb
- 字符继续对称,例如 aab->aaba
假设您有一个指针,它跟踪字符串并指向最后一个继续潜在回文的字符。
(我将使用括号来表示指向的字符)
假设您从 aa(b) 开始并得到:
- 'a'(情况 3),将指针向左移动并检查它是否是 'a'(它是)。你现在有 a(a)b。
- 'c'(案例 1),你不期望一个 'c',在这种情况下,你从头开始,现在你有 aab(c)。
真正棘手的情况是 2,因为不知何故你必须知道你刚刚得到的字符并没有影响对称性,它只是延伸了中间。为此,您必须持有一个额外的指针来跟踪高原(中间)边缘所在的位置。例如,您有 (b)baabb,而您刚刚获得了另一个 'b',在这种情况下,您必须知道将指针重置到此处的中间高原底部:bbaa(b)bb。由于我们要使用恒定时间,因此您必须先在此处握住指针(您没有时间寻找高原边缘)。现在如果你得到另一个'b',你知道你仍然在那个高原的边缘,你把指针保持在原来的位置,所以 bbaa(b)bb -> bbaa(b)bbb。现在,如果你得到一个'a',你就知道'b'
有了这三种情况,我认为所有的基础都涵盖了。如果您想检查当前字符串是否是回文,请检查第一个指针(不是高原的边缘指针)是否在索引 0 处。
这可能会对您有所帮助: http: //arxiv.org/pdf/1308.3466v1.pdf
如果您存储最后 $k$ 个输入符号,您可以轻松找到长度为 $k$ 的回文。
如果您使用本文的算法,您可以找到回文的中点及其长度的长度估计。