Project Euler第11题Python代码求助:运行卡顿致电脑死机
解决Project Euler第11题:四相邻数字最大乘积的性能问题
作为Python纯新手刚啃Project Euler的题,碰到代码跑慢甚至死机的情况真的太正常了——你的核心思路完全没问题:遍历每个数字计算相邻四元组的乘积,再找最大值,只是细节上的处理不当导致了性能灾难。我来帮你拆解问题,一步步优化:
你代码跑慢/死机的大概率原因
- 边界处理错误,导致无效计算甚至无限循环
比如你遍历到网格边缘的数字时,强行往某个方向取3个相邻数,可能触发索引越界,而如果你的错误处理(比如瞎写的try-except或者错误的条件判断)没做好,会导致程序反复尝试无效的计算,甚至陷入死循环。 - 重复计算冗余的四元组
比如横向的[a,b,c,d]和反向的[d,c,b,a]乘积完全一样,但你可能两边都算了,平白增加一倍的计算量;如果所有方向都重复处理,计算量会翻好几倍。 - 用大列表存储所有乘积,浪费内存
你把所有乘积都塞进列表再用max(),其实完全没必要——每算出一个乘积,直接和当前记录的最大值比较就行,省掉了维护大列表的内存开销和后续遍历列表的时间。 - 网格数据类型错误
如果你的网格是从文本里读进来的字符串,没转成整数就直接相乘,会变成字符串拼接(比如"8" * "2"会变成"88"),生成超长字符串占用大量内存,直接导致死机。
优化后的代码示例(新手友好)
先把Project Euler第11题的网格转成二维整数列表(这里只写前两行,你可以补全剩下的):
# 替换成完整的20×20网格 grid = [ [8, 2, 22, 97, 38, 15, 0, 40, 0, 75, 4, 5, 7, 78, 52, 12, 50, 77, 91, 8], [49, 49, 99, 40, 17, 81, 18, 57, 60, 87, 17, 40, 98, 43, 69, 48, 4, 56, 62, 0], # ... 剩下的18行省略 ] max_product = 0 grid_size = len(grid) # 1. 横向:同一行连续4个数字 for row in range(grid_size): # 列只遍历到grid_size-4,避免j+3越界 for col in range(grid_size - 3): current_product = grid[row][col] * grid[row][col+1] * grid[row][col+2] * grid[row][col+3] if current_product > max_product: max_product = current_product # 2. 纵向:同一列连续4个数字 for row in range(grid_size - 3): for col in range(grid_size): current_product = grid[row][col] * grid[row+1][col] * grid[row+2][col] * grid[row+3][col] if current_product > max_product: max_product = current_product # 3. 正对角线:从左上到右下连续4个数字 for row in range(grid_size - 3): for col in range(grid_size - 3): current_product = grid[row][col] * grid[row+1][col+1] * grid[row+2][col+2] * grid[row+3][col+3] if current_product > max_product: max_product = current_product # 4. 反对角线:从左下到右上连续4个数字 for row in range(3, grid_size): for col in range(grid_size - 3): current_product = grid[row][col] * grid[row-1][col+1] * grid[row-2][col+2] * grid[row-3][col+3] if current_product > max_product: max_product = current_product print("最大乘积是:", max_product)
为什么这个代码更快?
- 只遍历有效范围:比如横向遍历列时,直接停在
grid_size-3,确保col+3不会超出网格边界,完全避免了无效计算和索引错误。 - 无重复计算:每个四元组只算一次(比如横向只从左到右,不用反向),减少了冗余的运算量。
- 内存高效:用单个变量
max_product记录最大值,不用存储所有乘积,内存占用极低。 - 逻辑清晰:四个方向分开处理,新手能一眼看懂每个循环在干嘛,调试也方便。
给你的小建议
如果你还是看不懂其他解答,先从这种拆分方向的简单代码入手——Project Euler的题核心是逻辑,不是炫技,先把能跑对、跑快的代码写出来,再慢慢优化更简洁的写法。
内容的提问来源于stack exchange,提问作者Gabriel Almeida




