跳台阶
描述
一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个 n 级的台阶总共有多少种跳法(先后次序不同算不同的结果)。
数据范围:1≤𝑛≤40
要求:时间复杂度:𝑂(𝑛) ,空间复杂度: 𝑂(1)
示例1
输入:2
返回值:2
说明:
青蛙要跳上两级台阶有两种跳法,分别是:先跳一级,再跳一级或者直接跳两级。因此答案为2
示例2
输入:7
返回值:21
对于本题,前提只有 一次 1阶或者2阶的跳法。
a.如果两种跳法,1阶或者2阶,那么假定第一次跳的是一阶,那么剩下的是n-1个台阶,跳法是f(n-1);
b.假定第一次跳的是2阶,那么剩下的是n-2个台阶,跳法是f(n-2)
c.由a\b假设可以得出总跳法为: f(n) = f(n-1) + f(n-2)
d.然后通过实际的情况可以得出:只有一阶的时候 f(1) = 1 ,只有两阶的时候可以有 f(2) = 2
e.可以发现最终得出的是一个斐波那契数列:
| 1, (n=1)
f(n) = | 2, (n=2)
| f(n-1)+f(n-2) ,(n>2,n为整数)
class Solution:
def jumpFloor(self , number: int) -> int:
# 如果输入的数字小于或等于0,返回0
if number <= 0:
return 0
# 初始化变量 a, b 和 sum
a, b, sum = 0, 0, 1
# 从1循环到给定的数字(包括这个数字)
for _ in range(1, number + 1):
# 将 a 更新为之前 b 的值
a = b
# 将 b 更新为之前 sum 的值
b = sum
# 将 sum 更新为新的 a 和 b 的和
sum = a + b
# 返回最终的 sum 值
return sum
在牛客编译环境下,由于没有指定输入输出,故只写出类,函数即可,后台会自动调用验证结果。上述代码同样符合条件。
动态规划版本如下:
class Solution:
def jumpFloor(self, number: int) -> int:
# 初始化 dp 数组,dp[i] 表示跳到第 i 级台阶的方法数
# dp[0] = 1 表示跳到第 0 级台阶的方法数(1种,什么都不做)
# dp[1] = 1 表示跳到第 1 级台阶的方法数(1种,从第 0 级台阶跳到第 1 级)
# dp[2] = 2 表示跳到第 2 级台阶的方法数(2种,从第 0 级跳到第 2 级,或从第 1 级跳到第 2 级)
# [0]*number 初始化其他位置的值为 0,用于存储后续的结果
dp = [1, 1, 2] + [0] * number
# 从第 3 级台阶开始,计算每一级台阶的方法数
for i in range(2, number + 1):
# 跳到第 i 级台阶的方法数等于跳到第 i-1 级和跳到第 i-2 级台阶的方法数之和
dp[i] = dp[i - 1] + dp[i - 2]
# 返回跳到第 number 级台阶的方法数
return dp[number]
满足时间复杂度为O(n),空间复杂度为O(1)的代码
class Solution:
def jumpFloor(self, number: int) -> int:
if number <= 2:
return max(1, number)
prev2, prev1 = 1, 2 # 初始化前两个状态
for _ in range(3, number + 1):
current = prev1 + prev2 # 当前状态等于前两个状态之和
prev2, prev1 = prev1, current # 更新前两个状态
return prev1 # 返回最后一个状态
# 测试示例
solution = Solution()
print(solution.jumpFloor(5)) # 输出 8
-
初始化前两个状态:
prev2
表示跳到第 0 级台阶的方法数(初始化为 1)。prev1
表示跳到第 1 级台阶的方法数(初始化为 2)。
-
循环更新状态:
- 从第 3 级台阶开始循环到
number
,每次更新当前台阶的方法数current
为prev1 + prev2
。 - 然后更新
prev2
和prev1
的值为当前台阶的前两个状态。
- 从第 3 级台阶开始循环到
-
返回结果:
- 最后返回
prev1
,即跳到第number
级台阶的方法数。
- 最后返回
这种方法只用到了常数个额外变量来存储状态,因此空间复杂度为 O(1)。同时,只需一次线性循环来计算所有的状态,因此时间复杂度为 O(n),其中 n 是台阶的级数。