代码随想录算法训练营Day45 | 动态规划(7/17) LeetCode 70. 爬楼梯 (进阶) 322. 零钱兑换 279.完全平方数

开始第七天的练习!

第一题

70. Climbing Stairs

You are climbing a staircase. It takes n steps to reach the top.

Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top?

在刚进行动态规划的练习时候,曾经用简单的方法做过这道题。但是现在学了背包问题的思想,可以在原题上进行改动:一步一个台阶,两个台阶,三个台阶,…,直到 m个台阶。问有多少种不同的方法可以爬到楼顶呢?


1阶,2阶,… m阶就是物品,楼顶就是背包。
每一阶可以重复使用,例如跳了1阶,还可以继续跳1阶。
问跳到楼顶有几种方法其实就是问装满背包有几种方法。

  1. 确定dp数组以及下标的含义
    1. dp[i]:爬到有i个台阶的楼顶,有dp[i]种方法。
  2. 确定递推公式
    1. 本题dp[i]有几种来源,dp[i - 1],dp[i - 2],dp[i - 3] 等等,即:dp[i - j]
    2. 那么递推公式为:dp[i] += dp[i - j]
  3. dp数组如何初始化、
    1. 既然递归公式是 dp[i] += dp[i - j],那么dp[0] 一定为1,dp[0]是递归中一切数值的基础所在,如果dp[0]是0的话,其他数值都是0了。
    2. 下标非0的dp[i]初始化为0,因为dp[i]是靠dp[i-j]累计上来的,dp[i]本身为0这样才不会影响结果。
  4. 确定遍历顺序
    1. 这是背包里求排列问题,即:1、2 步 和 2、1 步都是上三个台阶,但是这两种方法不一样!
    2. 所以需将target放在外循环,将nums放在内循环。
    3. 每一步可以走多次,这是完全背包,内循环需要从前向后遍历。
  5. 举例来推导dp数组
class Solution:
    def climbStairs(self, n: int) -> int:
        dp = [0]*(n+1)
        dp[0] = 1

        for i in range(n+1):
            for j in range(1,m+1):
                if i - j >= 0:
                    dp[i] += dp[i-j]

        return dp[-1]

第二题

322. Coin Change

You are given an integer array coins representing coins of different denominations and an integer amount representing a total amount of money.

Return the fewest number of coins that you need to make up that amount. If that amount of money cannot be made up by any combination of the coins, return -1.

You may assume that you have an infinite number of each kind of coin.

由于硬币总数量无限,因此这是完全背包问题。

class Solution:
    def coinChange(self, coins: List[int], amount: int) -> int:
        dp = [float('inf')] * (amount + 1)  
        dp[0] = 0  

        for coin in coins:  
            for i in range(coin, amount + 1):  
                if dp[i - coin] != float('inf'): 
                    dp[i] = min(dp[i - coin] + 1, dp[i]) 

        if dp[amount] == float('inf'):  
            return -1
        return dp[amount]  

第三题

279. Perfect Squares

Given an integer n, return the least number of perfect square numbers that sum to n.

perfect square is an integer that is the square of an integer; in other words, it is the product of some integer with itself. For example, 149, and 16 are perfect squares while 3 and 11 are not.

仍然是完全背包问题

class Solution:
    def numSquares(self, n: int) -> int:
        dp = [float('inf')] * (n + 1)
        dp[0] = 0

        for i in range(1, n + 1): 
            for j in range(1, int(i ** 0.5) + 1):  
                dp[i] = min(dp[i], dp[i - j * j] + 1)

        return dp[n]

你可能感兴趣的:(LeetCode,动态规划,leetcode,算法)