标签:== 大于 状态 还需要 off output nat 编码 div
公式:f[0] = 0; f[1]= 1; f[n] = f[n-1] + f[n-2]
如果直接用递归实现的话,可能会出现重复计算问题:
def fibo(n):
if n<2: return n
return fibo(n-1) + fibo(n-2)
这里如果我们计算f(4), 则会有 f(4) = f(3) + f(2); f(3) = f(2) + f(1) 两处计算f(2) 的地方。一个很自然的改进方案:每次计算fibo(n) 是看看是不是已经计算过,如果计算过就直接返回之间计算出来的值:
def fibo(n):
if n < 2: return n
dp = [-1] * len(n+1)
dp[0],dp[1] = 0,1
return f(n)
def f(n):
if dp[n] != -1: return dp[n]
dp[n] = f(n-1) + f(n-2)
return dp[n]
当然,我们可以不递归的方法,直接用数组记录:
def fibo(n):
if n<2: return n
dp = [0]*len(n+1)
dp[1] = 1
for i in range(2,n+1):
dp[i] = dp[i-1] + dp[i-2]
return dp[n]
主要到,我们实际上一直在使用的只用dp[n-1],dp[n-2],dp[n], 所以我们还可以优化下内存空间:
def fibo(n):
if n<2: return n
fn_1,fn = 0,1
n -=2
while n>=0:
fn,fn_1 = fn+fn_1,fn
n -= 1
return fn
接下来说说一些相似的题目:
一个青蛙可以跳上一个台阶,也可以跳上两个台阶,求改青蛙跳上一个n级的台阶共有多少种跳法?
首先考虑状态变化过程:青蛙到达当前台阶是更低一阶的台阶或者是更低二阶的台阶跳上来的。所以有:
f[0] =0, f[1] = 1, f[2] = 2
f[n] = f[n-1] + f[n-2] 当 n>2时
代码:
def jump(n):
if n <= 2: return n
fn,fn_1 = 1,2
n -= 2
while n>0:
fn,fn_1 = fn+fn_1,fn
n -= 1
return fn
我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形。请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法?
对于\(2 \times n\) 的矩形,如果从左向右开始填充,再最左边我们可先竖着放一个或者横着放两个,那么剩下的情况就是f(n-1) 与 f(n-2)。 所以有公式:
f[0] = 0; f[1] =1; f[2] = 2
f[n] = f[n-1] + f[n-2] 当 n>2 时
代码同上边的青蛙跳台阶题目一样。
现有信息通过如下编码方式编码:
'A' -> 1
'B' -> 2
...
'Z' -> 26
先给一个编码后的字符串,请判断有多少种解码方式.
Example 1:
Input: "12"
Output: 2
Explanation: It could be decoded as "AB" (1 2) or "L" (12).
Example 2:
Input: "226"
Output: 3
Explanation: It could be decoded as "BZ" (2 26), "VF" (22 6), or "BBF" (2 2 6).
这个如同上面的题目一样,从左向右扫描,也和矩阵覆盖问题一样,有两种可能:
这里以"226"为例子,当前指向6时 为例子
可以覆盖"2",也即是f(n) 可以从f(n-2)状态转移来
也可以覆盖 "22" , 也即是f(n) 可以从状态f(n-1) 转移过来。当然我们还需要检查n-2和n-1构成的编码是否不大于26.
所以我们有状态转移方程:
f[0] = 0; f[1] = 1;
if s[n] == '0':
f[n] = f[n-1]
elif s[n] != '0' and int(s[n-1:n+1]) < 27:
f[n] = f[n-1] + f[n-2]
elif s[n]!= '0' and int(s[n-1:n+1]) >26:
f[n] = f[n-1]
代码:
def numDecodings(self,s:str)->int:
if s==None: return 0
fn,fn_1 = 1,1
for i in range(0,len(s)):
new_fn = 0 if s[i]=='0' else fn
if i>0 and (s[i-1]=='1' or s[i-1]=='2' and s[i]<'7'):
# 注意这里使用 (s[i-1]=='1' or s[i-1]=='2' and s[i]<'7') 代替 int(s[i-1:i+1])
# 防止出现以0开始的非法编码,如 00,01等.
new_fn += fn_1
fn,fn_1 = new_fn,fn
return fn
标签:== 大于 状态 还需要 off output nat 编码 div
原文地址:https://www.cnblogs.com/lmingde/p/11773242.html