运行Project Euler问题Python代码触发Memory Error,求错误原因与解法
代码问题说明
- 最核心的逻辑错误是
x += 1的缩进位置错误:它被放在了if判断的分支内,只有当x是3或5的倍数时才会自增。一旦遇到不满足条件的数值(比如x=1),程序会进入else分支直接跳过,x的值永远不会更新,直接进入无限死循环。如果你的输入n值极大,就算没有死循环,持续向列表追加符合条件的数值也会快速耗尽内存。 - 第二个设计缺陷是没有必要用列表存储所有符合条件的数值再求和,这种实现对内存的消耗会随着n的增大线性上升,n足够大时必然触发MemoryError。
修复方案
基础修复版(修正逻辑+直接累加)
只需要把x的自增逻辑移到if判断外,同时去掉不必要的列表存储,直接累加结果即可:
def euler_1(n): x = 0 total = 0 while x < n: if x % 3 == 0 or x % 5 == 0: total += x # 无论当前数是否符合条件,都要遍历下一个数 x += 1 return total
最优数学解法(O(1)时间/空间复杂度)
这个问题可以用容斥原理直接计算,不需要遍历所有数值,不管n多大都不会有内存和速度问题:
小于n的3或5的倍数总和 = 小于n的3的倍数总和 + 小于n的5的倍数总和 - 小于n的15的倍数总和(15是3和5的最小公倍数,这部分被重复加了两次需要扣除)
对应代码实现:
def euler_1(n): max_num = n - 1 # 计算各倍数的项数 count_3 = max_num // 3 count_5 = max_num // 5 count_15 = max_num // 15 # 等差数列求和公式:项数*(首项+末项)//2,首项都是对应倍数,末项是倍数*项数 sum_3 = 3 * count_3 * (count_3 + 1) // 2 sum_5 = 5 * count_5 * (count_5 + 1) // 2 sum_15 = 15 * count_15 * (count_15 + 1) // 2 return sum_3 + sum_5 - sum_15
内容的提问来源于stack exchange,提问作者wes BOREland
相关产品推荐
相关产品推荐

