string - 试图找到一个更有效的算法

标签 string algorithm performance time-complexity

二进制字符串是每个字符为“0”或“1”的字符串。一个二进制字符串 S 是好的当且仅当对于 S 的每个子字符串,“0”的数量小于或等于“1”的数量。

字符串S的子串可以通过从S的开头删除几个(或零个)字符和从S的结尾删除几个(或零个)字符,从S中至少留下两个字符来获得。例如,如果S = "abcdfab",则"abcd"、"fab"、"bcdfa"、"abcdfab"是S的子串,而"abab"、""、"d"、"adcdab"不是S的子串。

我想找出一种方法来检查长度为 N 的二进制字符串是否正确。

天真的方法是检查这个二进制字符串的每个子字符串,其时间复杂度为 O(N^2),是否有一种算法可以具有 O(N) 或更好的时间复杂度?

最佳答案

为了使每个单个(两个或更多字符)子字符串至少具有与零一样多的 1,不能有连续的零 - 事实上,您至少需要 两个每对零之间的一个。那是因为字符串 010 无效,但是0110没有两个字符的子字符串违反了您的约束。

所以算法是:

set oneCount to 2 # Zero at start of string is okay.
for each character ch in string:
    if ch is 0:
        if oneCount is less than 2:
            generate error
        set oneCount to 0
    else:
        increment oneCount

这实际上是 O(n) 时间,但您实际上可以通过分摊成本做得更好。由于在检查之前可能会对字符串进行多次修改操作,因此您可以推迟检查以降低摊销成本。

我的意思是缓存字符串的有效性,这样,如果您在没有修改它的情况下进行检查,只需返回缓存的值而不是重新检查。这是最粗略的摊销水平,但可能会单独带来改进:

define string = "", dirty = false, cachedValidity = true

define isValid():
    if dirty:
        cachedValidity = true
        set oneCount to 2
        for each character ch in string:
            if ch is 0:
                if oneCount is less than 2:
                    cachedValidity = false
                    exit for loop
                set oneCount to 0
            else:
                increment oneCount
    dirty = false
    return cachedValidity

然后您只需确保对字符串的任何操作都将 dirty 设置为 true,这在面向对象语言中实际上非常容易。

为了进一步优化,您不需要为所有 操作将dirty 设置为true,这实际上取决于您在做什么。字符串有效性在(至少)以下条件下不会改变:

  1. 如果您将一个插入到另一个旁边。
  2. 如果您删除一个介于其他两个之间的一个。
  3. 如果你在四个连续的中间插入一个零。

这些操作都不会影响有效性,因此它们不应设置 dirty 标志。您可能会在分析中发现其他内容,但这是一个良好的开端,可以让您进一步分摊检查成本。

关于string - 试图找到一个更有效的算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47148632/

相关文章:

c - Fortran 与 C : Mandelbrot benchmark

python - 根据字典对列表进行排序(初学者)

c++ - 检查字符串中的唯一字符

java - ArrayList.sort() 与 PriorityQueue

python - 从 pandas 或 dask 的数据库表中读取大数据

javascript - 是 "if (somestring in {' oneoption' :false, 'secondoption' :false})"considered bad practise in javascript?

c++ - 哪个是更好的字符串搜索算法? Boyer-Moore 还是 Boyer Moore Horspool?

Python将字符串添加到列表循环中

python - 使用 Levenshtein 距离作为 Python 中的启发式算法生成字符串的爬山算法?

javascript - 对于奇数和偶数长度的数字,如何最好地确定最右边数字左边的数字?