python - 降低阶梯式问题的时间复杂度(亚马逊面试问题)
问题描述
def step(n):
if (n==0) or (n==1):
return 1
elif n==2:
return 2
else:
return step(n-1) + step(n-2) + step(n-3)
n = int(input())
print(step(n))
对于输入 53798080,它需要 1 秒。它应该比满足测试用例要少得多。
解决方案
对于输入 53798080,它需要 1 秒。
我非常怀疑这一点。您的代码堆栈在此输入上溢出。我相信这里发生的是输入30需要 1 秒才能产生输出53798080。通过输入 31,我们最多需要半分钟。
如果我们记住您的代码:
from functools import lru_cache
@lru_cache
def step(n):
if n == 0 or n == 1:
return 1
if n == 2:
return 2
return step(n-1) + step(n-2) + step(n-3)
正如@templatetypedef 解释的那样,它解决了速度问题。但是,它会在输入 500 以上时因堆栈溢出(假设您没有分配更多堆栈)而爆炸。我们可以将该范围加倍,并使用更有效且递归更少的算法来处理速度问题而无需记忆:
def step(n, prev1=2, prev2=1, prev3=1):
if 0 <= n <= 1:
return 1
if n == 2:
return prev1
return step(n - 1, prev3 + prev2 + prev1, prev1, prev2)
这将处理高达 999 的输入并在几分之一秒内产生结果:
> time python3 test.py
1499952522327196729941271196334368245775697491582778125787566254148069690528296568742385996324542810615783529390195412125034236407070760756549390960727215226685972723347839892057807887049540341540394345570010550821354375819311674972209464069786275283520364029575324
0.032u 0.011s 0:00.04 100.0% 0+0k 0+0io 0pf+0w
>
(添加@lru_cache
到此代码中会将输入范围缩小回原来的范围,并且在速度方面没有区别。)
推荐阅读
- arangodb - pyArango 与 Foxx 微服务
- c# - 对 Xml 格式函数进行单元测试
- java - 当我使用 jsoup 库请求 URL 时发生错误的响应代码
- react-native - 在 Android (RN 0.61.5) 中反应原生自动链接问题
- docker - 为什么我得到 x509:Azure DevOps docker push to registry 上的未知权威签署的证书
- node.js - 在 MongoDB 中,如何根据另一个字段有条件地更新具有不同值的文档
- visual-studio-code - Visual Studio 代码导入自定义 css 和 js 扩展
- php - 如何在 PHP 中理解这个算法
- mongodb - Teiid Spring Boot:如何将特定的 MongoDB 集合公开为 OData 实体?
- php - 根据输入,使用 PHP 创建 TABLE