最經典的爬臺階問題
遞歸樹的思路:
紅色的有重複計算,所以用空間換時間的思想來優化遞歸。
# -*- encoding: utf-8 -*-
class Solution:
"""對於遞歸樹來說,使用純遞歸的方法,O(n)=2^n,有重複計算的情況"""
def stairs_climbing(self, n: int) -> int:
if n == 2: return 2
if n == 1: return 1
return self.stairs_climbing(n - 1) + self.stairs_climbing(n - 2)
def climbStairs(self, n: int) -> int:
return self.stairs_climbing(n)
class Solution2:
"""使用了一個全局變量用來存儲算過的值,從上到下的遞歸方法,
這裏還有一個不太好理解的地方是當有0個臺階時,沒法走,也算是一種方法。
"""
def stairs_climbing(self, n: int) -> int:
if self.memo[n] == 0:
self.memo[n] = self.stairs_climbing(n - 1) + self.stairs_climbing(n - 2)
return self.memo[n]
def climbStairs(self, n: int) -> int:
self.memo = [0] * (n + 1)
self.memo[0], self.memo[1] = 1, 1
return self.stairs_climbing(n)
class Solution3:
"""同樣使用一個全局變量來存儲計算過的值,不過是從下到上的方法,不用遞歸"""
def climbStairs(self, n: int) -> int:
memo = [0] * (n + 1)
memo[0], memo[1] = 1, 1
if memo[n] == 0:
for i in range(2, n + 1):
memo[i] = memo[i - 1] + memo[i - 2]
return memo[n]
if __name__ == '__main__':
solution = Solution3()
rest = solution.climbStairs(100)
print(rest)
那到底什麼是動態規劃呢?
可以把複雜問題分解爲子問題,並且子問題還可以優化。
當然這裏還涉及到兩種思想,分別是
- 從上到下的思考問題(使用遞歸)
- 從下到上的實現(可以不使用遞歸)