一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶(n为正整数)总共有多少种跳法。
数据范围:
进阶:空间复杂度 , 时间复杂度
进阶:空间复杂度 , 时间复杂度
class Solution: def jumpFloorII(self, number): # write code here res = [0,1,2] while len(res) <= number: res.append(sum(res)+1) return res[number]
class Solution: def jumpFloorII(self, number): # write code here y = 2 if number == 0: return None if number == 1: return 1 if number == 2: return 2 else: for _ in range(number-2): y *= 2 return ypython非递归,f(n) = 2*f(n-1),还要注意number与循环次数的关系
class Solution: def jumpFloorII(self, number): way = [0,1] for i in range(2,number+1): way.append(sum(way)+1) return way[number]
# -*- coding:utf-8 -*- class Solution: def jumpFloorII(self, number): while number>0: return pow(2,number-1) return 0
# -*- coding:utf-8 -*- class Solution: # 递归(时间复杂度比较高) def jumpFloorII(self, number): if number <= 1: return number return self.jump(number) def jump(self, number): count = 0 if number == 0: return 1 if number < 0: return 0 for i in range(1,number+1): count += self.jump(number - i) return count class Solution: # 动态规划(自上而下) def jumpFloorII(self, number): self.dp = [-1]*(number+1) if number <= 1: return number return self.jump(number) def jump(self, number): count = 0 if number == 0: return 1 if number < 0: return 0 if self.dp[number] != -1: return self.dp[number] for i in range(1,number+1): count += self.jump(number - i) self.dp[number] = count return count class Solution: # 动态规划(自下而上) def jumpFloorII(self, number): if number <= 1: return number dp = [0]*(number+1) dp[0] = 1 dp[1] = 1 dp[2] = 2 for i in range(3,number+1): for j in range(i): dp[i] += dp[j] return dp[-1]
一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。
1.1. 数学思想分析
1.2. 规律分析法
先事先对n=1,2,3,4,5级台阶情况进行分析,点出它们所有可能的跳法,之后观察规律,可以发现它们是呈现以2的幂分布的,可以得出通项公式如下:
同样,也可以根据下面的规律得出公式1的计算式:
规律 f(1)=1 2**0 f(2)=2 2**1 f(3)=4 2**2 f(4)=8 2**3 f(5)=16 2**4
一两行代码即可实现,关键就是分析清楚题目的规律。
# -*- coding:utf-8 -*- class Solution: def jumpFloorII(self, number): # write code here #f(1)=1 2**0 #f(2)=2 2**1 #f(3)=4 2**2 #f(4)=8 2**3 #f(5)=16 2**4 if number == 0: return 0 return 2**(number-1)
# -*- coding:utf-8 -*- # 解题思路:动态规划状态转义方程式 # dp[n] = dp[n - 1] + dp[n - 2] + ... + dp[2] + dp[1] + dp[0] # 第n项为前n项的和(包括0, 0表示n - n, 即跳一次跳上n这种情况),dp[0] == 1 # 总结规律发现dp[n] = 2^ n -1 (n ! = 0) class Solution: def jumpFloorII(self, number): # write code here if number <= 0: return 0 else: return pow(2, number - 1)
# -*- coding:utf-8 -*- class Solution: def jumpFloorII(self, number): # write code here if number==1: return 1 if number==2: return 2 dp=[0 for i in range(number+1)] dp[0]=1 dp[1]=1 dp[2]=2 sum=4 for i in range(3,number+1): dp[i]=sum sum+=sum return dp[-1]
关于本题,前提是n个台阶会有一次n阶的跳法。分析如下:
f(1) = 1
f(2) = f(2-1) + f(2-2) //f(2-2) 表示2阶一次跳2阶的次数。
f(3) = f(3-1) + f(3-2) + f(3-3)
...
f(n) = f(n-1) + f(n-2) + f(n-3) + ... + f(n-(n-1)) + f(n-n)
说明:
1)这里的f(n) 代表的是n个台阶有一次1,2,...n阶的 跳法数。
2)n = 1时,只有1种跳法,f(1) = 1
3) n = 2时,会有两个跳得方式,一次1阶或者2阶,这回归到了问题(1) ,f(2) = f(2-1) + f(2-2)
4) n = 3时,会有三种跳得方式,1阶、2阶、3阶,
那么就是第一次跳出1阶后面剩下:f(3-1);第一次跳出2阶,剩下f(3-2);第一次3阶,那么剩下f(3-3)
因此结论是f(3) = f(3-1)+f(3-2)+f(3-3)
5) n = n时,会有n中跳的方式,1阶、2阶...n阶,得出结论:
f(n) = f(n-1)+f(n-2)+...+f(n-(n-1)) + f(n-n) => f(0) + f(1) + f(2) + f(3) + ... + f(n-1)
6) 由以上已经是一种结论,但是为了简单,我们可以继续简化:
f(n-1) = f(0) + f(1)+f(2)+f(3) + ... + f((n-1)-1) = f(0) + f(1) + f(2) + f(3) + ... + f(n-2)
f(n) = f(0) + f(1) + f(2) + f(3) + ... + f(n-2) + f(n-1) = f(n-1) + f(n-1)
可以得出:
f(n) = 2*f(n-1)
7) 得出最终结论,在n阶台阶,一次有1、2、...n阶的跳的方式时,总得跳法为:
| 1 ,(n=0 )
f(n) = | 1 ,(n=1 )