提高查找字符串列表的LPS的时间复杂度

时间:2018-10-01 08:23:45

标签: python string time-complexity longest-substring knuth-morris-pratt

我一直在处理以下提示:

您会得到一个数组A,该数组由仅由字母“ a”和“ b”组成的字符串组成。 每个字符串都经过许多操作,其中:

  • 在时间1,您将每个字符串循环旋转1个字母。
  • 在时间2,您将新旋转的字符串循环旋转2个字母。
  • 在时间3,将新旋转的字符串循环旋转3个字母。
  • 在时间i,您将新旋转的字符串循环旋转i%个长度(字符串)字母。

    一段时间后,字符串将等于其原始值。 字符串等于其自身后,其字母将从第一个字母开始再次旋转(过程重置)。因此,如果字符串花了t时间回到原始位置,则在t + 1时将旋转一个字母,而该字符串将成为2t时间的原始字符串。 您必须找到最短的时间,其中最大的字符串数等于其原始值。 由于这个时间可能非常大,因此应将答案取模109 + 7。

    注意:您的解决方案将在多个测试用例上运行,因此请在使用它们后清除全局变量。

    我的想法是循环遍历每个字符串,生成lps数组以检查是否存在子字符串,使用随着t上升字符串位置旋转t(t + 1)/ 2的事实,并检查1确定2个最小t的情况。但是,我遇到大量字符串超过时间限制的错误。

    我正在寻找有关如何调整程序以减少时间复杂度的建议。

    def gcd(A,B):
        if B> A:
            A,B = B,A
        while B!=0:
            temp = B
            B=A%B
            A=temp
        return A
    
    
    def solve(A):
        times = []
        for i in range (0, len(A)):
            j=1
            m=len(A[i])
            lps = [0]*m
            p=0
            for k in range(1,m):     #generate LPS of KMP to find longest subsequence
                while p > 0 and A[i][k] != A[p]:
                    p = lps[p-1]
                if A[i][k]==A[i][p]:
                    p+=1
                lps[i]=j
            if lps[-1] > 0:
                while ((j*(j+1))//2)%lps[-1] != 0:
                    j+=1
                times.append(j)
            else: 
                while ((j*(j+1))//2)%len(A[i]) != 0:
                    j+=1
                times.append(j)
        lcm = times[0]
        for i in times[1:]:
            lcm = lcm*i/gcd(lcm, i)
        lcm = int(lcm%((1e9)+7))
        return lcm
    
    ###testing below this point
    A=["a", "ababa", "aba"]
    print(solve(A))
    

    遍历每个列表是O(n),其中n是列表数
    我的印象是生成lps列表是O(n + m)
    然后再将确定t的while循环嵌套一次,因此总的时间复杂度应为O(n * k),其中k = 2 *平均列表长度-1(又称最大t值)。

    我想知道任何有关如何提高时间复杂度的建议,或者是一般代码。

  • 0 个答案:

    没有答案