python中以下代码的时间复杂度是多少?

时间:2018-07-24 08:07:17

标签: python

以下是从python中的字符串中删除循环字母的代码。我想知道这段代码的时间复杂度。更具体地说,第if string_1[i] not in char_found:行的时间复杂度。在列表中搜索。

如果可能的话,也可以使用列表分配的空间来解释。

def remove_recorring_char(string_1):
    result = ""
    char_found = []
    for i in range(0,len(string_1)):
        if string_1[i] not in char_found:
            char_found.append(string_1[i])
            result = result+string_1[i]
    return result

if __name__== "__main__":
    print(remove_recorring_char("aabbbcc"))
    print(remove_recorring_char("chdsgdsgggsggsjddaaxcvcj"))

1 个答案:

答案 0 :(得分:3)

if string_1[i] not in char_found:

此行有两件事:

首先,它访问string_1[i]。这需要固定的时间,因为字符串基本上只是字符数组。

然后,它在列表char_found中进行搜索,将该字符string_1[i]与每个元素进行比较,直到匹配为止。这(最坏的情况)是花费char_found长度的线性时间。而且,由于char_found可能(最坏的情况)是string_1[:i]中的所有字符,因此string_1的长度是线性的。

因此,这一行是O(N)

当然,该行位于外部循环中,显然更O(N)for i in range(0,len(string_1)):。因此,两者的组合为O(N**2)

即使将in测试固定为恒定时间,也要在循环内执行result = result+string_1[i]。字符串串联在字符串长度上是最坏的情况。 CPython和PyPy的最新版本进行了一些优化,因此有时会分摊固定时间,例如追加到列表中,但是Python语言不保证这些优化。最坏的情况是result也和string_1一样长。因此,除非您的口译员特别好,否则整件事仍然是O(N**2)


您可以通过做两个小改动将整个事情简化为O(N)

首先,对set使用list而不是char_found。搜索集合并添加到集合中,都是摊销的固定时间操作。

第二,对list使用str而不是result,然后最后进行result = ''.join(result)。追加到列表将摊销固定时间。将列表转换回字符串当然是线性时间,但是您不必在循环中执行它,所以很好。