Day 45 DP:70. 爬楼梯 (进阶), 322. 零钱兑换, 279. 完全平方数

70. 爬楼梯

  • 思路
    • example
    • 完全背包 + 排列
      • 背包外循环,物品(步数)内循环

求装满背包有几种方法,递推公式一般都是dp[i] += dp[i - nums[j]];

  • 复杂度. 时间:O(n), 空间: O(n)
class Solution:
    def climbStairs(self, n: int) -> int:
        dp = [0] * (n+1)
        dp[0] = 1
        m = 2
        for j in range(1, n+1): # 背包
            for i in range(1, m+1): # 物品
                if j >= i:
                    dp[j] += dp[j-i]
        return dp[n]
  • 复习之前写法 (index i改为j更方便统一理解)
class Solution:
    def climbStairs(self, n: int) -> int:
        dp = [0 for _ in range(n+1)]
        dp[0] = 1
        dp[1] = 1
        for i in range(2, n+1):
            dp[i] = dp[i-1] + dp[i-2] 
        return dp[n]

322. 零钱兑换

  • 思路
    • example
    • 完全背包
      • 求最小的硬币个数,所以组合问题,排列问题都可以,不影响取最小值 (5+5+1=1+5+5=5+1+5)。这里按照 完全背包 + 组合 的思路来 (遍历:先物品,再背包)。
  • 复杂度. 时间:O(n*amount), 空间: O(amount)
class Solution:
    def coinChange(self, coins: List[int], amount: int) -> int:
        dp = [amount+1 for _ in range(amount+1)]
        dp[0] = 0
        for coin in coins:
            for j in range(coin, amount+1):
                dp[j] = min(dp[j], dp[j-coin]+1)
        return dp[amount] if dp[amount] != amount+1 else -1
  • 完全背包+排列 (2D)
class Solution:
    def coinChange(self, coins: List[int], amount: int) -> int:
        n = len(coins) 
        dp = [[amount+1 for _ in range(amount+1)] for _ in range(n+1)]
        dp[0][0] = 0
        for j in range(amount+1):
            for i in range(1, n+1):
                coin = coins[i-1]
                if j >= coin:
                    dp[i][j] = min(dp[i-1][j], dp[i][j-coin]+1) # dp[i][j-coin]+1 !!!
                else:
                    dp[i][j] = dp[i-1][j] 
        return dp[n][amount] if dp[n][amount] != amount+1 else -1

279. 完全平方数

  • 思路
    • example
    • 完全背包,最小数量:组合,排列均可
  • 复杂度. 时间:O(?), 空间: O(?)
    • 先背包,再物品 (完全背包+排列)
class Solution:
    def numSquares(self, n: int) -> int:
        dp = [float('inf') for _ in range(n+1)]
        dp[0] = 0
        for j in range(1, n+1): # 背包
            i = 1
            while j >= i*i: # 物品
                dp[j] = min(dp[j], dp[j-i*i] + 1)
                i += 1
        return dp[n] 
  • 先物品,再背包 (完全背包+组合)
class Solution:
    def numSquares(self, n: int) -> int:
        dp = [n+1 for _ in range(n+1)]
        dp[0] = 0 # !!!
        for num in range(1, n+1):
            if num**2 > n:
                break 
            for j in range(num**2, n+1):
                dp[j] = min(dp[j], dp[j-num**2]+1)
        return dp[n]
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容