第4篇 斐波那契數列python實現
知識點:遞歸和循環
要求
大家都知道斐波那契數列,現在要求輸入一個整數n,請你輸出斐波那契數列的第n項。
n<=39
斐波那契數列的定義: F(0)=0,F(1)=1, F(n)=F(n-1)+F(n-2)(n>=2,n∈N*)
代碼
版本1:
class Solution:
def Fibonacci(self, n):
# 定義: F(0)=0,F(1)=1, F(n)=F(n-1)+F(n-2)(n>=2,n∈N*)
if n == 0:
return 0
elif n == 1:
return 1
else:
return self.Fibonacci(n-1) + self.Fibonacci(n-2)
問題:效率太低,滿足不了oj的效率要求。且有很多重複計算!
改進:可以從下往上計算,從0,1一直疊加到n,就像人工做計算那樣,從而避免重複
class Solution:
def Fibonacci(self, n):
# 定義: F(0)=0,F(1)=1, F(n)=F(n-1)+F(n-2)(n>=2,n∈N*)
if n == 0:
return 0
elif n == 1:
return 1
else:
fib0 = 0
fib1 = 1
for _ in range(2, n+1):
fib0, fib1 = fib1, fib0 + fib1
return fib1
跳臺階
要求
一隻青蛙一次可以跳上1級臺階,也可以跳上2級。求該青蛙跳上一個n級的臺階總共有多少種跳法。
思路
青蛙某次可以是在之前跳了(n-1)級的基礎上,再跳了1級到達第n級,也可以是在之前跳了(n-2)級的基礎上,再跳了2級到達第n級……依次類推,發現其實是一個斐波那契數列。
代碼
class Solution:
def jumpFloor(self, number):
# 思路:斐波那契數列問題,從後往前看,f(n) = f(n-1) + f(n-2)
# f(1) = 1, f(2) = 2
if number <= 2:
return number
else:
fib1 = 1
fib2 = 2
for _ in range(3, number+1):
fib1, fib2 = fib2, fib1+fib2
return fib2
變態跳臺階
要求
一隻青蛙一次可以跳上1級臺階,也可以跳上2級……它也可以跳上n級。求該青蛙跳上一個n級的臺階總共有多少種跳法。
思路
思路與上一題類似,只不過在第n次時,要考慮到前面的各種情況,也就是說,到第n個臺階之前,可以是從(0)一步登天過來的,也可以是從(1)跳過來的,也可是從(2)跳過來的,把各種情況加起來。
思考時是從n往前思考,但實現時,要從前往後累加,避免重複計算。
代碼
class Solution:
def jumpFloorII(self, number):
# f(n) = once + f(1) + f(2) + ... + f(n-3) + f(n-2) + f(n-1)
# f(n-1) = once + f(1) + f(2) + ... + f(n-3) + f(n-2)
# f(n-2) = once + (1) + f(2) + ... + f(n-3)
# ...
# f(4) = once + f(1) + f(2) + f(3)
# f(3) = once + f(1) + f(2)
# f(2) = once + f(1)
# f(1) = once
# once = 1
# 前面加上once表示考慮到之前未跳過,一次就跳到這一級的情況,once應該爲1
return 2 ** (number-1)
矩形覆蓋
要求
我們可以用21的小矩形橫着或者豎着去覆蓋更大的矩形。請問用n個21的小矩形無重疊地覆蓋一個2*n的大矩形,總共有多少種方法?
思路
寬度爲n,可以用一個小矩形豎着放,佔據1寬度,也可以用兩個小矩形橫着放,佔據2寬度。這不還是跳臺階問題嘛
代碼
class Solution:
def jumpFloor(self, number):
# 思路:斐波那契數列問題,從後往前看,f(n) = f(n-1) + f(n-2)
# f(1) = 1, f(2) = 2
if number <= 2:
return number
else:
fib1 = 1
fib2 = 2
for _ in range(3, number+1):
fib1, fib2 = fib2, fib1+fib2
return fib2