加速算法,查找给定范围内的倍数

沉默的根

我对如何加快将给定范围内的倍数求和的算法感到困惑。这是针对codewars.com上的问题的,这里是该问题的链接codewars链接

这是代码,我将在底部解释发生了什么

import itertools

def solution(number):
        return multiples(3, number) +  multiples(5, number) - multiples(15, number)

def multiples(m, count):

    l = 0
    for i in itertools.count(m, m):
        if i < count:
            l += i
        else:
            break
    return l

print solution(50000000) #takes 41.8 seconds
#one of the testers takes 50000000000000000000000000000000000000000 as input

# def multiples(m, count):
#     l = 0
#     for i in xrange(m,count ,m):
#         l += i
#     return l

所以基本上这个问题要求用户返回一个数字中3和5的所有倍数的和。这是测试人员。

test.assert_equals(solution(10), 23)
test.assert_equals(solution(20), 78)
test.assert_equals(solution(100), 2318)
test.assert_equals(solution(200), 9168)
test.assert_equals(solution(1000), 233168)
test.assert_equals(solution(10000), 23331668)

我的程序没有问题,没有找到正确的答案。当输入较大时会出现问题。当传递数字(例如50000000)时,需要40秒钟以上的时间才能返回答案。我被要求接受的输入之一是50000000000000000000000000000000000000000000000,这是一个巨大的数字。这也是itertools.count()我使用xrange我的第一次尝试但范围不能处理大于ac类型的数字的原因。我知道问题最慢的部分是倍数方法...但是它仍然比我第一次尝试使用列表理解并检查是否i % 3 == 0 or i % 5 == 0有想法的速度更快

沙申克

对于大量用户,此解决方案应该更快。

def solution(number):
    number -= 1
    a, b, c = number // 3, number // 5, number // 15
    asum, bsum, csum = a*(a+1) // 2, b*(b+1) // 2, c*(c+1) // 2
    return 3*asum + 5*bsum - 15*csum

解释:

取从1到n的任何顺序:

1, 2, 3, 4, ..., n

它的总和将始终由公式给出n(n+1)/2如果您认为表达式(1 + n) / 2只是计算此特定数字序列的平均值或算术平均值捷径,则可以轻松证明这一点。因为average(S) = sum(S) / length(S),如果取任何数字序列的平均值,然后将其乘以序列的长度,则得出序列的总和。

如果给定一个数字n,并且我们希望某个给定k的倍数之和等于n,包括n,那么我们想求和:

k + 2k + 3k + 4k + ... xk

其中xk是k的小于或等于n的最高倍数。现在注意,该总和可以分解为:

k(1 + 2 + 3 + 4 + ... + x)

我们已经有了k,所以现在我们需要寻找的只是x。如果将x定义为最大数,则可以将k乘以得到小于或等于n的自然数,那么我们可以使用Python的整数除法来获得数x:

n // k == x

一旦找到x,就可以使用以前的公式找到任何给定的k到给定的n的倍数之和:

k(x(x+1)/2)

我们给定的三个k是3、5和15。

我们在这行中找到x:

a, b, c = number // 3, number // 5, number // 15

在此行中计算它们的倍数之和,直到n:

asum, bsum, csum = a*(a+1) // 2, b*(b+1) // 2, c*(c+1) // 2

最后,在这行中将它们的总和乘以k:

return 3*asum + 5*bsum - 15*csum

我们有我们的答案!

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

加快找到给定范围内倍数的算法

来自分类Dev

查找给定范围内 n 个数字的倍数

来自分类Dev

确定值是否在倍数范围内的算法

来自分类Dev

查找给定范围内的缺失值

来自分类Dev

用于将特定值添加到范围内的数组元素的快速算法?

来自分类Dev

如何加速算法?

来自分类Dev

R +查找算法以匹配相同元素范围内的值

来自分类常见问题

在给定范围内查找最大序列-Spark / Scala

来自分类Dev

查找数组中给定范围内的元素数

来自分类Dev

从给定范围内的数组中查找峰值

来自分类Dev

查找在给定时间范围内修改的文件

来自分类Dev

查找给定范围内的所有插槽

来自分类Dev

从给定范围内的数组中查找峰值

来自分类Dev

查找落在给定范围内的索引

来自分类Dev

在指定的日期范围内如何查找给定的日期

来自分类Dev

Excel公式查找给定范围内的日期(整列)

来自分类Dev

计算给定范围内O(1)复杂度的数字的倍数?

来自分类Dev

计算给定范围内O(1)复杂度的数字的倍数?

来自分类Dev

查找矩形内所有点的快速算法

来自分类Dev

x在大数范围内的倍数

来自分类Dev

大数范围内x的倍数

来自分类Dev

java查找具有在范围内加到10的倍数的数字的质数

来自分类Dev

Excel公式-查找给定范围内的任何日期是否与给定年份匹配

来自分类Dev

查找给定的日期范围是否在MySQL中的另一个日期范围内

来自分类Dev

查找给定的日期范围是否在MySQL中的另一个日期范围内

来自分类Dev

给定日期范围,查找在该范围内重叠的事件

来自分类Dev

查找范围内的序列

来自分类Dev

查找日期在范围内

来自分类Dev

查找范围内的值

Related 相关文章

热门标签

归档