【问题标题】:Related to string and substring与字符串和子字符串相关
【发布时间】:2020-01-18 04:37:45
【问题描述】:

计算字符串中唯一子串总数的有效方法是什么

【问题讨论】:

    标签: django


    【解决方案1】:

    简介

    如果我们看看下面的双循环:

    for i in range(l):
        for j in range(1,l-i+1):
            mylist.append(string[i:j+i])
    

    然后就很清楚为什么您的解决方案在某些测试用例中以Runtime Error 终止 - 循环中的空间复杂度太高了! mylist 中的元素数量与 n2 成正比,其中n 是原始字符串的长度。根据任务描述,字符串长度可以接近10^6个字符,你的mylist大小可以分别变成10^12

    更糟糕的是,mylist 的元素不仅仅是单个字符,而是原始字符串的子字符串。因此,空间复杂度实际上是 O(n3)。由于您的示例输入字符串的长度为5000,因此您将超过512MB,这是here 所述的最大允许阈值。

    如何提高空间复杂度

    您必须意识到,您不需要任何mylist 来计算 StuartKevin 的分数。相反,您可以直接在循环中计算他们的分数。为什么?因为它已经生成了原始字符串的所有子字符串,其中string[i] 是给定子字符串的第一个字符。然后,如果它是元音,则增加 Kevin 的分数,否则 - Stuart 的分数:

    stuart=0
    kevin=0  
    for i in range(l):
        for j in range(1,l-i+1):
            if string[i] in vowel:
                kevin += 1
            else:
                stuart += 1   
    

    如何提高时间复杂度

    在上一段中,我们做了很大的改进,因为Runtime Error消失了,但是解决方案对于一些测试用例仍然会超时,因为它的时间复杂度仍然太高 - O(n2).

    要改进它,你必须意识到以string[i] 开头的子字符串的数量是len(string) - i。因此,不需要内部循环,原始双循环可以简化为 O(n) 时间复杂度解决方案:

    stuart = 0
    kevin = 0  
    for i in range(l):
        if string[i] in vowel:
            kevin += (l - i)
        else:
            stuart += (l - i)
    

    完整代码

    def minion_game(string):
        l = len(string)
        vowel=['A','E','I','O','U']
    
        stuart = 0
        kevin = 0  
        for i in range(l):
            if string[i] in vowel:
                kevin += (l - i)
            else:
                stuart += (l - i)
    
        if kevin > stuart:
            print(f'Kevin {kevin:d}')
        elif stuart > kevin:
            print(f'Stuart {stuart:d}')
        else:
            print('Draw')
    

    【讨论】:

      猜你喜欢
      • 2023-04-08
      • 2020-12-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-15
      • 2014-06-09
      • 2016-06-09
      • 1970-01-01
      相关资源
      最近更新 更多