代码随想录算法训练营第四十五天| 70. 爬楼梯(进阶版)、322. 零钱兑换、279. 完全平方数。

70. 爬楼梯(进阶版)

题目链接:力扣

题目要求:

        假设你正在爬楼梯。需要 n 阶你才能到达楼顶。每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?

示例 1:

输入:n = 2
输出:2
解释:有两种方法可以爬到楼顶。
1. 1 阶 + 1 阶
2. 2 阶
  • 1 <= n <= 45

总结:

        这题可以抽象为完全背包问题,n阶,相当于背包的大小,每次可以爬1或两个台阶,代表每次可以装的物品大小,每个物品可以无限选,dp[j]相当于楼顶高度大小为j阶,有多少种方法可以爬到楼顶。又因为每次选择的顺序不同,方案也不同,所以这里也是需要找排列的,不是找组合,所以背包要在外层遍历,物品在内层遍历,同时因为是每个物品无限次选,故为完全背包问题,所以背包的遍历可以正序遍历,每个dp[j]都需要由dp[0]推导出来,需要dp[0]=1;

class Solution {
    public int climbStairs(int n) {
        int[] dp = new int[n + 1];
        //物品栏只有一步和二步的情况
        int[] weight = {1,2};
        dp[0] = 1;
        for(int j = 0;j <= n;j++){
            for(int i = 0;i < weight.length;i++){
                if(j >= weight[i]){
                    dp[j] += dp[j - weight[i]];
                }
            }
        }
        return dp[n];
    }
}

322. 零钱兑换

题目链接:力扣

题目要求:

        给你一个整数数组 coins ,表示不同面额的硬币;以及一个整数 amount ,表示总金额。

计算并返回可以凑成总金额所需的 最少的硬币个数 。如果没有任何一种硬币组合能组成总金额,返回 -1 。

你可以认为每种硬币的数量是无限的。

示例 1:

输入:coins = [1, 2, 5], amount = 11
输出:3 
解释:11 = 5 + 5 + 1
  • 1 <= coins.length <= 12
  • 1 <= coins[i] <= 231 - 1
  • 0 <= amount <= 104

总结:

        这题不同面额的硬币代表不同的物品,凑成的总金额amount代表背包的大小,这里的每种硬币可以无限次选取,我们需要返回可以凑成总金额所需要的最少硬币的个数,这题跟每次选择的硬币顺序是没关系的,所以不是选排列,选组合就可以,故两层循环的谁在外谁在内无所谓,就按照常规的物品在外背包在内就可以,又因为是完全背包问题,所以内层的背包循环正序遍历皆可以,非0的项都需要设置成最大的一个数。因为防止影响比较最小值的结果。

class Solution {
    public int coinChange(int[] coins, int amount) {
        int[] dp =new int[amount + 1];
        int max = Integer.MAX_VALUE;
        for(int i = 0;i <= amount;i++){
            dp[i] = max;
        }
        dp[0] = 0;
        for(int i = 0;i < coins.length;i++){
            for(int j = coins[i];j <= amount;j++){
                if(dp[j - coins[i]] != max){
                    dp[j] = Math.min(dp[j],dp[j - coins[i]] + 1);
                }
            }
        }
        return dp[amount] == max? -1:dp[amount];
    }
}

279. 完全平方数

题目链接:力扣

题目要求:

        给你一个整数 n ,返回 和为 n 的完全平方数的最少数量 。完全平方数 是一个整数,其值等于另一个整数的平方;换句话说,其值等于一个整数自乘的积。例如,149 和 16 都是完全平方数,而 3 和 11 不是。

示例 1:

输入:n = 12
输出:3 
解释:12 = 4 + 4 + 4
  • 1 <= n <= 104

总结:

        这题也是可以抽象为一个完全背包问题,也是找最少数目,和上一题差不多类似,不是排列,所以两个循环顺序无所谓,完全背包,所以内循环的背包需要正序遍历。

class Solution {
    public int numSquares(int n) {
        int[] dp = new int[n + 1];
        int max = Integer.MAX_VALUE;
        for(int i = 0; i <= n;i++){
            dp[i] = max;
        }
        dp[0] = 0;
        for(int i = 1;i*i <= n;i++){
            for(int j = i*i;j <= n;j++){
                if(dp[j - i*i] != max){
                    dp[j] = Math.min(dp[j],dp[j-i*i] + 1);
                }
            }
        }
        return dp[n];
    }
}

你可能感兴趣的:(算法,数据结构,leetcode,动态规划,java)