标签:10 begin return res 斐波 base bmatrix end 那契
题目:剑指 Offer 10- I. 斐波那契数列(E)
解题思路1:
本身是一道很简单的题啊,是当时学习递归时接触到的第一个例子,递归的思想可以,但是当n很大时,重复计算太多,会超时,所以采用动态规划更好一些。一般最初的想法是,设置一个n长的数组把之前的结果都保存下来,这样也可以但是空间复杂度为\(O(N)\),python的话直接使用两个变量即可,一个存储f(n-1),一个存储f(n-2)。
时间:\(O(N)\)
空间:\(O(1)\)
class Solution:
def fib(self, n: int) -> int:
# if n < 1: return n
# else:
# sum = [0, 1]
# for i in range(2, n + 1):
# sum.append(sum[i - 1] + sum[i - 2])
# return sum[n] % (1000000007)
a, b = 0, 1
for i in range(n):
a, b = b, (a + b) % 1000000007
return a % 1000000007
优质解答:矩阵快速幂(参考自官方)
数列递推使用矩阵快速幂以降低时间复杂度。将递推式转化为矩阵形式,如下
\[\begin{bmatrix} F(N)\\ F(N-1) \end{bmatrix} = \begin{bmatrix} 1 && 1 \\ 1 && 0 \end{bmatrix} \begin{bmatrix} F(N-1)\\ F(N-2) \end{bmatrix} \]推到F(0)和F(1),则变成
\[\begin{bmatrix} F(N)\\ F(N-1) \end{bmatrix} = \begin{bmatrix} 1 && 1 \\ 1 && 0 \end{bmatrix}^{N-1} \begin{bmatrix} F(1)\\ F(0) \end{bmatrix} \]所以主要任务就变成求矩阵的N-1次幂,将矩阵A进行两两合并,如果N为偶数,则变成求\((A^2)^{N/2}\),N为奇数的话,则需要额外在乘一次A,变成求\((A^2)^{N/2}\times A\),同理在对\(A^2\)进行合并,依次循环,则矩阵求幂就变成只需求\(logN\)次即可。
时间:\(O(logN)\)
空间:\(O(1)\)
class Solution:
def fib(self, n: int) -> int:
if n < 2: return n
MOD = 10 ** 9 + 7
def mul(m1, m2):
res = [[0, 0], [0, 0]]
for i in range(2):
for j in range(2):
res[i][j] = (m1[i][0]*m2[0][j] + m1[i][1]*m2[1][j]) % MOD
return res
def matrix_pow(base, power):
res = [[1, 0], [0, 1]]
while power > 0:
if power & 1: res = mul(res, base)
power >>= 1
base = mul(base, base)
return res
base = [[1, 1], [1, 0]]
res = matrix_pow(base, n - 1)[0][0]
return res
标签:10,begin,return,res,斐波,base,bmatrix,end,那契 来源: https://www.cnblogs.com/BakeryOwner/p/16099186.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。