思路
看到这题时,心想:就这就这???斐波那契数列嘛,简单。
#python3
class Solution:
def climbStairs(self, n: int) -> int:
if n<3: return n
return self.climbStairs(n-1) + self.climbStairs(n-2)
写完之后,超时了…
看来还是得学习一波,这里记录一下各种解法。
# python3
# 直接递归解法,容易超时,python可以加个缓存装饰器,这样也算是将递归转换成迭代的形式了
# 除了这种方式,还有增加步长来递归,变相的减少了重复计算
# 还有一种方法,在递归的同时,用数组记忆之前得到的结果,也是减少重复计算
class Solution:
@functools.lru_cache(100) # 缓存装饰器
def climbStairs(self, n: int) -> int:
if n<3: return n
return self.climbStairs(n-1) + self.climbStairs(n-2)
# 直接DP,新建一个字典或者数组来存储以前的变量,空间复杂度O(n)
class Solution:
def climbStairs(self, n: int) -> int:
dp = {}
dp[1] = 1
dp[2] = 2
for i in range(3,n+1):
dp[i] = dp[i-1] + dp[i-2]
return dp[n]
# 还是DP,只不过是只存储前两个元素,减少了空间,空间复杂度O(1)
class Solution:
def climbStairs(self, n: int) -> int:
if n==1 or n==2: return n
a, b, temp = 1, 2, 0
for i in range(3,n+1):
temp = a + b
a = b
b = temp
return temp
221. 最大正方形
提示:
- m == matrix.length
- n == matrix[i].length
- 1 <= m, n <= 300
- matrix[i][j] 为 ‘0’ 或 ‘1’
思路
典型动态规划问题。
用 dp[i][j] 来表示以第 i 行,第 j 列处为右下角的最大正方形的边长。
仅当该位置为1时,才有可能存在正方形。且递推公式为:
dp[i][j] = min( dp[i-1][j-1], dp[i-1][j], dp[i][j-1] ) + 1
含义为若当前位置为1,则此处可以构成的最大正方形的边长,是其正上方,左侧,和左上界三者共同约束的,且为三者中的最小值加1。
特判,若matrix为空,返回0
初试化matrix的行 h,列 w,初始化dp=[[0,⋯,0],⋯,[0,⋯,0]],维度为(h+1)*(w+1),这样便于处理边界。初试化最大边长maxline = 0。
遍历dp数组,遍历行 i,遍历区间[1,h+1):
遍历列 j,遍历区间[1,w+1):
若matrix[i-1][j-1]==“1”,此时可能存在正方形:
令:dp[i][j] = min(dp[i-1][j-1], dp[i-1][j], dp[i][j-1]) + 1
并更新最大边长maxline = max(maxline, dp[i][j])
返回面积maxline ** 2
时间复杂度:O(m * n)
空间复杂度:O(m * n)
# python3
class Solution:
def maximalSquare(self, matrix: List[List[str]]) -> int:
h = len(matrix)
w = len(matrix[0])
dp = [[0]*(w+1) for _ in range(h+1)]
maxline = 0
for x in range(h):
for y in range(w):
if matrix[x][y] == '1':
dp[x+1][y+1] = min(dp[x][y], dp[x+1][y], dp[x][y+1]) + 1
maxline = max(dp[x+1][y+1], maxline)
return maxline ** 2