鉴于字符串s对查询(i, j, k, l)
快速响应:
-1
if s[i..j] < s[k..l]
0
if s[i..j] = s[k..l]
1
if s[i..j] > s[k..l]
假设
i <= j
k <= l
0 <= i, k < s.length - 1
换句话说,执行大量的词典子字符串比较。
s[i..j]
是一个(j - i + 1)
- 字符子字符串,从位置i
开始(从0开始索引)并在位置j
(包括端点)结束。
s[i..j] < s[i..j+1]
,这个单词的前缀被认为小于单词本身。
由于查询的数量为O(s.length)
,因此应快速回答查询,即以对数或恒定时间进行查询。我听说有传言说可以实现恒定时间解决方案(显然有一些预处理)。
到目前为止,我考虑使用散列函数,例如
h[i] = (h[i - 1] + x^i * s[i]) mod m
其中x > 26
(字母表的大小)和m
为素数。
s[i..j]
的哈希值将通过从h[i]
中减去h[j]
并将x
除以(尚未确定的)幂来计算。
这种方法有一个重要问题 - 它不允许我检查少于/大于条件。我最初认为h[i..j] < h[k..l]
应该暗示s[i..j] < s[k..l]
。这是无效的,因为
azzz
和b
,让我们假设m
足够大,以便我们不必执行模运算。很明显h['azzz'] > h['b']
但azzz < b
。这是作业。我不是在寻找实现,而是我应该了解更多的一般性想法和问题。完整的解决方案当然是受欢迎的,但不是必需的。
答案 0 :(得分:1)
我猜你是来自波兰,所以这里有很棒的文章,对这个问题非常好: http://www.mimuw.edu.pl/~jrad/wpg/drobne_oszustwo.pdf
实际上,您可以使用散列来检查哪个单词更大。您必须使用bin搜索来查找这两个子字符串的第一个后缀,它们具有不同的哈希值,然后检查下一个字母。这将表明更多的话。复杂度为O(logm)
,其中m是较短子字符串的大小。你可以在O(1)
中找到哈希(使用权力的预处理),然后在O(logm)
的bin搜索中找到哈希。希望它有所帮助:)
答案 1 :(得分:0)
有许多微不足道的案例可以让查询立即返回,无需预处理。这是分而治之的方法。将问题分解为子问题(在这种情况下使用Python语言):
# compare the first character of the substrings
if s[i] < s[k]:
return -1
if s[i] > s[k]:
return 1
# first characters are the same
if i == k: # same substring?
if j > l: # first substring is longer
return 1
if j < l: # second substring is longer
return -1
return 0 # identical substring
# worst case: same first character but different substrings
# compare s[(i+1)..j], s[(k+1)..l], maybe with a hash
希望这减少了您的问题集。我认为可能有更聪明的哈希函数。