Mar.4-5 爬楼梯(简单)& 最大正方形(中等)

70. 爬楼梯
在这里插入图片描述

思路

看到这题时,心想:就这就这???斐波那契数列嘛,简单。

#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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值