【问题标题】:substrings with sum equals to a number总和等于数字的子字符串
【发布时间】:2021-12-08 14:34:29
【问题描述】:

我有一个字符串 S='n1,n2,n3.......nk' (例如'3,0,4,0,3,1,0,1,0,1,0,0 ,5,0,4,2') 和一个数字 m= S (es 9)。我想知道 sum 等于 m 的子串有多少。

我使用了这个似乎有效的代码。我有一个 1 秒的超时时间,这段代码在几毫秒的测试中失败了,并且有很长的数字字符串。我该如何优化它?

m = 9
numbers = list(map(int,S.split(",")))
result  = 0
sums    = numbers
for i in range(len(numbers)):
    result += sums.count(m)
    sums   = [a+b for a,b in zip(sums,numbers[i+1:]) ]
print(result)``` 

【问题讨论】:

  • 你可以试试递归函数,或者itertools.combinations
  • 这是哪里来的?我们可以自己在某个地方在线测试吗?有什么限制?

标签: python string list substring


【解决方案1】:
m = 9

c = 0
for i in range(len(numbers)):
    for j in range(len(numbers)-i):
        sum = 0
        for k in numbers[i:i+j]:
            sum += k
            if sum == m:
                c += 1
            if sum > m: # strict >, thanks to Tim Roberts
                break

print(c)

【讨论】:

  • 这里有一个微妙的问题。你真的想要sum > m;对于所有的 0,将有多个子字符串具有相同的开头并加起来为 m。
  • 列表创建编号[i:i+j] 非常昂贵。对于优雅的解决方案,请查看一些经典书籍,例如 libgen.rs/search.php?req=Donald+E.+Knuth&column=author
【解决方案2】:

计算前缀和的 O(n) 解决方案。例如,如果前缀和是 13,那么要得到 9,你想减去前缀和 4,所以查看前缀和 4 出现的频率:

from collections import Counter

S = '3,0,4,0,3,1,0,1,0,1,0,0,5,0,4,2'
m = 9

numbers = map(int, S.split(","))
result = 0
presum = 0
presums = Counter([presum])
for number in numbers:
    presum += number
    result += presums[presum - m]
    presums[presum] += 1

print(result)

也适用于负数。

【讨论】:

    猜你喜欢
    • 2021-12-08
    • 2015-02-05
    • 2016-06-28
    • 1970-01-01
    • 2020-07-02
    • 1970-01-01
    • 2015-04-22
    • 2013-10-09
    • 2013-01-11
    相关资源
    最近更新 更多