题目描述
n<=39
时间限制:1秒 空间限制:32768K 热度指数:153571
思路
1、用递归来实现,但是递归存在调用栈溢出的风险。
调用栈溢出是因为递归的计算中,每次函数调用在内存栈中分配空间,而每个进程的栈的容量都是有限的。
当递归调用的层级太多时,就会超出栈的容量,从而导致调用栈的溢出。
2、从下往上计算。根据 f(0) 和 f(1) 算出 f(2),再根据 f(1) 和 f(2) 算出 f(3)...以此类推,就可以算出 f(n)。
时间复杂度是 O(n).
参考代码
Python实现
# -*- coding:utf-8 -*-
class Solution:
def Fibonacci(self, n):
# write code here
tempArray = [0, 1]
if n <= 0:
return 0
elif n == 1:
return 1
elif n == 2:
return 1
else:
for i in range(2, n + 1):
tempArray[i % 2] = tempArray[0] + tempArray[1]
return tempArray[i % 2]
题目推广
一只青蛙一次可以跳上 1 级台阶,也可以跳上 2 级台阶。求问该青蛙跳上一个 n 级的台阶总共有多少种跳法。
思路
其实这是一个斐波那契数列的应用。青蛙要跳上 1 级台阶时,有 1 种跳法;青蛙要跳上 2 级台阶时,有 2 种跳法;
(第一种:先跳 1 级,再跳 1 级;第二种:直接跳 2 级)
这可以抽象为:要跳 n 级,先跳 1 级,再考虑跳 n - 1 级;先跳 2 级,再考虑跳 n - 2 级。
所以跳 n 级的跳法:f(n) = f(n - 1) + f(n - 2),这就是斐波那契数列的公式。
参考代码
# -*- coding:utf-8 -*-
class Solution:
# 青蛙跳台阶, 每次可以跳1级或2级
def jumpFloor(self, number):
# write code here
tempArray = [1, 2]
if number >= 3:
for i in range(3, number + 1):
tempArray[(i + 1) % 2] = tempArray[0] + tempArray[1]
return tempArray[(number + 1) % 2]
题目推广
将上题中的条件改为“一次可以跳上 1 级台阶,一次也可以跳上 2 级台阶,...,一次也可以跳上 n 级台阶”,求青蛙跳
上 n 级台阶的跳法?
思路
青蛙跳 1 级台阶的跳法是 f(1) = 1
青蛙跳 2 级台阶的跳法是 f(2) = 1 + f(1) = 2
青蛙跳 3 级台阶的跳法是 f(3) = 1 + f(1) + f(2) = 4
....
青蛙跳 n 级台阶的跳法是 f(n) = 1 + f(1) + f(2) + ... + f(n - 1) = 2^(n - 1)
其中:1 表示一次性跳上 n 级台阶的方法
参考代码
# -*- coding:utf-8 -*-
class Solution:
# 可以跳 1 级,也可以跳 2 级,... ,也可以跳 n 级
def jumpFloorII(self, number):
ans = 1
if number >= 2:
for i in range(number-1):
ans = ans * 2
return ans
总结
1、遇到需要多次重复计算的问题,通常是用递归或循环两种方法来实现的;
2、递归:在一个函数的内部调用这个函数本身;
3、循环:通过设置计算的初始值及终止条件,在一个范围内重复运算;
4、想要算法 / 代码简单,用递归;
5、递归会产生调用栈溢出,原因是递归调用的层级太多,会超过调用栈的容量;
6、面试优先写出递归算法,实现简单;
7、面试官要求改进算法,再使用循环实现;