首页 > 其他分享 >剑指offer103:最少的硬币数目

剑指offer103:最少的硬币数目

时间:2022-12-13 11:34:58浏览次数:42  
标签:offer103 硬币 int coins 总额 amount 最少 dp


题目:

给定不同面额的硬币 coins 和一个总金额 amount。编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回 -1。

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

示例一:

输入:coins = [1, 2, 5], amount = 11

输出:3

解释:11 = 5 + 5 + 1

示例二:

输入:coins = [2], amount = 3

输出:-1

示例三:

输入:coins = [1], amount = 0

输出:0

示例四:

输入:coins = [1], amount = 1

输出:1

示例五:

输入:coins = [1], amount = 2

输出:2

分析:

将每种面额的硬币看成一种物品,而将目标金额看成背包的容量,那么这个问题等价于求将背包放满时物品的最少件数,值得注意的时这里每种面额的硬币可以使用任意多次,因此这个问题不再是0-1背包问题了,而是一个无界背包问题。(也叫完全背包问题)

用函数f(i,j)表示前i种硬币(coins[0,…,i-1])凑出总额为j需要的硬币的最少数目,当使用0枚标号为i-1的硬币时,f(i,j)=f(i-1,j),当使用1枚标号为i-1的硬币时,f(i,j)等于f(i-1,j-coins[i-1])+1,以此类推当使用k枚标号为i-1的硬币时,f(i,j)等于f(i-1,j-kcoins[i-1])+k(用前i-1种硬币凑出总额j-kcoins[i-1]需要的最少硬币数目,再假设k枚标号为i-1的硬币),由于目标时求出硬币数目的最小值,因此f(i,j)是上述所有情况的最小值:

剑指offer103:最少的硬币数目_算法


如果硬币有n种,目标总额为t,那么f(n,t)就是问题的解。

当j=0时也就是总额为0时,f(i,0)=0,也就是从前i种硬币中选出0个硬币,使总额等于0.当i等于0且j大于0时,即用0种硬币凑出大于0的总额显然不可能因此可以用一个特殊值代替。

第二种思路:

剑指offer103:最少的硬币数目_背包问题_02


之前相当于横着从右往左计算,这种方式类似从上往下算,算完一列再算下一列,用函数f(i)表示凑出总额为i的硬币需要的最少数目,需要注意的是,这个函数只有一个参数i表示硬币的总额,如果目标总额为t那么f(t)就是整个问题的解。

代码:

import java.util.Arrays;

public class CoinChange {
// 第一种思路
public int coinChange1(int[] coins, int amount) {
int[] dp = new int[amount+1];
Arrays.fill(dp,amount+1);
dp[0] = 0;
for (int coin : coins) {
for (int j = amount; j >=1; j--) {
for (int k = 1; k*coin <=j; k++) {
dp[j] = Math.min(dp[j],dp[j-k*coin]+k);
}
}
}
return dp[amount] > amount ?-1:dp[amount];
}
// 第二种思路
//
public int coinChange2(int[] coins, int amount){
int[] dp = new int[amount+1];
// i代表总额,dp[i]代表凑出总额为i的最少硬币数目
for (int i = 1; i <=amount; i++) {
dp[i] = amount+1;
for (int coin:coins){
// 如果总额度大于等于该硬币的值
if (i>=coin){
dp[i] = Math.min(dp[i],dp[i-coin]+1);
}
}
}
return dp[amount]>amount ?-1:dp[amount];
}
}

剑指offer103:最少的硬币数目_Math_03


标签:offer103,硬币,int,coins,总额,amount,最少,dp
From: https://blog.51cto.com/u_15911055/5933487

相关文章

  • 剑指offer88:爬楼梯的最少成本
    题目:数组的每个下标作为一个阶梯,第i个阶梯对应着一个非负数的体力花费值cost[i](下标从0开始)。每当爬上一个阶梯都要花费对应的体力值,一旦支付了相应的体力值,就可以选......
  • 1827. 最少操作使数组递增
    1827.最少操作使数组递增classSolution{publicintminOperations(int[]nums){intn=nums.length;intres=0;for(inti=1;i......
  • 1827. 最少操作使数组递增 ----- 贪心算法
    给你一个整数数组 nums (下标从0开始)。每一次操作中,你可以选择数组中一个元素,并将它增加 1 。比方说,如果 nums=[1,2,3] ,你可以选择增加 nums[1] 得到 nums=......
  • 力扣每日一题2022.12.11---1827. 最少操作使数组递增
    给你一个整数数组 nums (下标从0开始)。每一次操作中,你可以选择数组中一个元素,并将它增加 1 。   比方说,如果 nums=[1,2,3] ,你可以选择增加 nums[1] 得到 n......
  • [研究中] 固定半径最少圆覆盖问题/固定数量最小半径覆盖问题
    一、固定半径最少圆覆盖问题背景:二维坐标轴中,给出n个点以及每个点的坐标(坐标为浮点型),和一个长度m(m为浮点型),求至少需要多个半径为m的圆可以把所有点覆盖住输入:第一行输入n......
  • 力扣 leetcode 1775. 通过最少操作次数使数组的和相等
    问题描述给你两个长度可能不等的整数数组nums1和nums2。两个数组中的所有值都在1到6之间(包含1和6)。每次操作中,你可以选择任意数组中的任意一个整数,将它变成......
  • 通过最少操作次数使数组的和相等
    题目给你两个长度可能不等的整数数组 nums1和 nums2 。两个数组中的所有值都在 1 到 6 之间(包含 1 和 6)。每次操作中,你可以选择任意 数组中的任意一个整数,......
  • 用最少的代码打造一个Mini版的gRPC框架
    在《用最少的代码模拟gRPC四种消息交换模式》中,我使用很简单的代码模拟了gRPC四种消息交换模式(Unary、ClientStreaming、ServerStreaming和DuplexStreaming),现在我们更近......
  • 排列硬币
    排列硬币一、题目描述总共有n和硬币,并计划将它们按阶梯状排列。对于一个有k行组成的阶梯,其第i行必须正好有i枚硬币。阶梯的最后一行可能是不完整的。给定一个数组n,计算......
  • 区间列表的交集 和相同的二元子数组 生成交替二进制字符串的最少操作数
    986.区间列表的交集List<int[]>list=newArrayList<>();intn=firstList.length;intm=secondList.length;inti=0;intj=0;while(i<n&&j<m){交......