斐波那契数索引查询程序超时问题及正整数斐波那契判定需求
解决斐波那契数索引查询超时问题及通用判断方法
先搞定你的超时难题
你的代码超时的核心问题是循环终止逻辑完全跑偏了——你用输入的目标数值来控制循环次数(i <= n + 2),当输入像1134903171这种大斐波那契数时,循环会执行上亿次,不超时才怪。
再给你拆解下代码里的其他小问题:
- 初始值和索引对应混乱:你定义
num=1、num_prev=1,却把起始索引i=1,导致斐波那契数和索引完全不匹配 - 终止条件逻辑错误:应该用生成的斐波那契数是否超过目标值来终止循环,而不是用目标值本身限制循环次数
修正后的高效代码
我们换个思路:生成斐波那契数直到它大于目标值,因为斐波那契数是指数增长的,哪怕是超大数值,循环次数也不会超过100次,绝对不会超时:
target = int(input()) # 这里采用常见的斐波那契定义:F(1)=1, F(2)=1, F(3)=2, F(4)=3... a, b = 1, 1 current_index = 1 # 处理前两个都是1的特殊情况(1对应索引1和2) if target == a: print("1, 2") else: while b <= target: if b == target: print(current_index + 1) break # 生成下一个斐波那契数 a, b = b, a + b current_index += 1 else: # 循环正常结束,说明目标数不在斐波那契数列中 print(-1)
测试输入1134903171(这个数是第45个斐波那契数),代码会快速定位到结果,不会出现超时。
通用需求:判断正整数是否为某n对应的第n个斐波那契数
上面的代码已经包含了判断逻辑,核心思路很简单:
- 从斐波那契数列的起始值开始生成
- 每次生成后和目标数对比:
- 相等则返回对应索引
- 生成的数超过目标数,说明目标数不在数列中,返回-1
- 注意处理前两个重复的1(如果你的斐波那契定义是前两项为1的话)
另外还有个数学捷径可以快速判断:一个数x是斐波那契数,当且仅当5x² + 4或5x² - 4是完全平方数。这个方法是O(1)时间复杂度,适合超大规模数值的快速判断:
import math def is_fibonacci(x): if x < 0: return False # 计算两个候选平方数 s1 = 5 * x * x + 4 s2 = 5 * x * x - 4 # 判断是否为完全平方数 sqrt_s1 = math.isqrt(s1) sqrt_s2 = math.isqrt(s2) return sqrt_s1 * sqrt_s1 == s1 or sqrt_s2 * sqrt_s2 == s2 target = int(input()) if is_fibonacci(target): print("该数是某个n对应的第n个斐波那契数") else: print("该数不属于斐波那契数列")
如果需要找对应的索引,还是循环生成的方法更直观好实现;数学方法适合只做判断的场景。
内容的提问来源于stack exchange,提问作者Peter W




