Hackerrank`超级函数字符串`因超时而终止

时间:2018-05-11 17:35:47

标签: string python-3.x python-2.7 substring

给定一个由小写字母组成的字符串p,计算函数的总和 F(p) = [len(p)**distinct(p)]%[10**9 + 7] F的所有可能的不同子串。由于结果非常大,所以以10 ** 9 + 7为模数打印。

例如对于' aba'它是:

  • F(a)= 1
  • F(ab)= 4
  • F(aba)= 9
  • F(b)= 1
  • F(ba)= 4

总和等于19。

以下是我的解决方案:

import os
import sys

def superFunctionalStrings(s):
    a=list()
    thesum=0
    length = len(s) + 1
    modu=10**9 + 7
    for j in range(length):
        for i in range(j+1, length):
            b = s[j:i]
            if b not in a:
                a.append(b)
                thesum += (len(b)**len(set(b)))%(modu)
    summ = thesum%(modu)       
    return(summ)         

我可以做些什么来优化它,以便超时不会发生? (我不允许猜测外部库)

2 个答案:

答案 0 :(得分:1)

你说"不同的子串",所以对于初学者来说,使用一个集合代替一个列表,这样就不会存储重复的子字符串,这样你就可以获得O(1)查找时间。此外,您不需要模数直到最后,并且Python支持添加任意大整数,因此您不一定需要循环内的模数。最后,我尝试使用理解,以便Python可以更快地循环。以下是这些建议给您留下的信息:

def superFunctionalStrings(s):
    a=list()
    thesum=0
    length = len(s) + 1
    modu=10**9 + 7
    substrs = {s[j:i] for j in range(length) for i in range(j+1, length)}
    return sum(len(b) ** len(set(b)) for b in substrs) % modu

采用这种方法,我获得了15-20倍的加速。

答案 1 :(得分:1)

一个可以消除O(n)复杂因素的变化是使a成为一个集合而不是列表。

要计算列表的b in a,需要搜索整个列表O(n)。或者,对集合进行计算b in a进行哈希处理,取O(1)。