5月23日零钱兑换+组合总和Ⅳ

377.组合总和Ⅳ

给你一个由 不同 整数组成的数组 nums ,和一个目标整数 target 。请你从 nums 中找出并返回总和为 target 的元素组合的个数。

题目数据保证答案符合 32 位整数范围。

示例 1:

复制代码
输入:nums = [1,2,3], target = 4
输出:7
解释:
所有可能的组合为:
(1, 1, 1, 1)
(1, 1, 2)
(1, 2, 1)
(1, 3)
(2, 1, 1)
(2, 2)
(3, 1)
请注意,顺序不同的序列被视作不同的组合。

示例 2:

复制代码
输入:nums = [9], target = 3
输出:0

提示:

  • 1 <= nums.length <= 200
  • 1 <= nums[i] <= 1000
  • nums 中的所有元素 互不相同
  • 1 <= target <= 1000

思路

这道题也是经典的完全背包问题,区别在于,组成target的零钱组合的排列顺序不一样也会算进组合总数,所以这道题本质求的是排列,而之前的题目求的是总和。

首先确定dp数组,定义一个大小为amount+1的一维dp数组,dpi表示能够组成总和i的组合个数。dp0初始化为1,dp数组的递推公式为dpj=dj+dpj-nums\[i](当j>=numsi)

但这其实是求组合数的思路,没有考虑到顺序的问题,所以我们应该在递推过程中先遍历target再遍历nums,这样对于每一种背包大小,nums中每个小于背包大小的值都会被考虑作为元素之和=背包大小的最后一个元素,所以不同顺序都会被考虑。

代码

java 复制代码
class Solution {
public int combinationSum4(int[] nums, int target) {
        int n=nums.length;
        int[] dp=new int[target+1];
        dp[0]=1;
        for(int i=1;i<=target;i++){
            for(int j=1;j<=n;j++){
                if(i>=nums[j-1]){
                    dp[i]+=dp[i-nums[j-1]];
                }
            }
        }
        return dp[target];
    }
}

322.零钱兑换

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

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

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

示例 1:

复制代码
输入:coins = [1, 2, 5], amount = 11
输出:3 
解释:11 = 5 + 5 + 1

示例 2:

复制代码
输入:coins = [2], amount = 3
输出:-1

示例 3:

复制代码
输入:coins = [1], amount = 0
输出:0

提示:

  • 1 <= coins.length <= 12
  • 1 <= coins[i] <= 231 - 1
  • 0 <= amount <= 104

思路

和474.一和零的思路差不多,区别在于这题求的是最小长度,所以需要在dp数组初始化上做一些改变。

首先定义一个一维dp数组,dpi表示可以凑成金额i所需的最小硬币个数。然后我们再考虑怎样初始化,首先组成金额0不需要选择任何硬币,所以dp0=0,然后若是要找出所需硬币的最小值,所有其它值都应该初始化为最大值+1,以便判断是否存在一种组合。

然后是递推公式,首先遍历每个硬币,然后由1到amount遍历每一个金额大小,如果金额大小大于当前硬币大小,则将dp金额大小更新为它与dp金额大小-硬币面值+1之间的较小值。最终判断dpamount若大于amount则返回-1,否则返回dpamount

代码

java 复制代码
class Solution {
    public int coinChange(int[] coins,int amount){
        int n=coins.length;
        int[] dp=new int[amount+1];
        Arrays.fill(dp,amount+1);
        dp[0]=0;
        for(int i=1;i<=n;i++){
            for(int j=1;j<=amount;j++){
                if(j>=coins[i-1]){
                    dp[j]=Math.min(dp[j],dp[j-coins[i-1]]+1);
                }
            }
        }
        return dp[amount]>amount?-1:dp[amount];
    }
}
相关推荐
blxr_3 分钟前
力扣hot100路径总和Ⅲhttps://leetcode.cn/problems/path-sum-iii/
算法·leetcode·职场和发展
noipp21 分钟前
【无标题】
c语言·数据结构·c++·算法
渡众机器人35 分钟前
第八届全球校园人工智能算法精英大赛-算法应用赛-渡众机器人智能体对抗挑战赛规则
人工智能·算法·机器人·自动驾驶·自主导航·对抗赛
郝学胜-神的一滴1 小时前
完全二叉树与堆底层原理深度剖析 | 手写C++大顶堆实现
java·开发语言·数据结构·c++·python·算法
青山木1 小时前
Hot 100 --- 缺失的第一个正数
算法·leetcode·哈希算法
农民小飞侠1 小时前
[leetcode] 165. Compare Version Numbers
java·算法·leetcode
装不满的克莱因瓶1 小时前
掌握语义分割经典模型 FCN——从像素分类到端到端分割的奠基之作
人工智能·python·深度学习·算法·机器学习·分类·数据挖掘
学计算机的计算基1 小时前
链表算法上篇:LeetCode 206/234/141/142/160/21 题解与易错点
java·笔记·算法·链表
大白话_NOI1 小时前
【洛谷 P2678】 [NOIP2015 提高组] 跳石头 超详细题解
c++·算法
xwz小王子2 小时前
ICRA 2026深度观察:全栈闭环成标配,中国具身智能势力显著崛起
大数据·人工智能·算法