ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

leetcode笔记——背包问题总结2

2019-06-16 16:54:29  阅读:435  来源: 互联网

标签:背包 硬币 int coins 笔记 amount 总金额 leetcode dp


1.找零钱的最少硬币数

322. Coin Change (Medium)

题目:

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

示例 1:

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

示例 2:

输入: coins = [2], amount = 3
输出: -1

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

思路:

这个是一个完全背包问题。硬币的不同面值对应物品的重量,总金额对应背包的总重量,每种硬币的数量都是无限的。设数组dp[i]表示总金额为i时,最少的硬币个数。这个需要注意的是初始值的问题,因为求解的是最小值,因此数组的初值不能设置为0,在这里我们设置成了amount+1.代码参考leetcode中评论里大神的代码,如下:

代码:

class Solution {
    public int coinChange(int[] coins, int amount) {
        int dp[] = new int[amount + 1];
        Arrays.fill(dp, amount + 1);//填充数组dp,使得数组的初始值均为amount+1;
        dp[0] = 0;
  for (int i =1;i<=coins.length;i++) {
        for (int j= coins[i-1]; j <= amount;j++) {//这块注意是正序,0-1背包问题中是逆序
                
             dp[j] = Math.min(dp[j-coins[i-1]]+1,dp[j]);
                
            }
        }
        return dp[amount] > amount ? -1 : dp[amount];//如果存在和为amount的组合,此时数组元素dp[amount]的值就会发生改变
    }
}
2.找零钱的硬币组合数

  518. Coin Change 2 (Medium)

题目:

给定不同面额的硬币和一个总金额。写出函数来计算可以凑成总金额的硬币组合数。假设每一种面额的硬币有无限个。

 

示例 1:

输入: amount = 5, coins = [1, 2, 5]
输出: 4
解释: 有四种方式可以凑成总金额:
5=5
5=2+2+1
5=2+1+1+1
5=1+1+1+1+1

示例 2:

输入: amount = 3, coins = [2]
输出: 0
解释: 只用面额2的硬币不能凑成总金额3。

示例 3:

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

思路:这个题也是一个完全背包问题。使用数组dp[i]表示总金额为i时,硬币的组合数,此时初始化每一个数组元素为0.但这个也好像动态规划一类的题。最后总金额为i的组合数等于不加当前的硬币时总金额就已经达到i的硬币组合数和加入当前硬币(此时的总金额数为i-硬币的面值)。

代码:

class Solution {
    public int change(int amount, int[] coins) {
       // if(coins==null||coins.length==0||amount==0) 这部分里面有一个特殊情况,就是金额为0,数组为空是结果为1。。
          //  return 0;
        int n=coins.length;
        int dp[]=new int[amount+1];
        dp[0]=1;
        for(int i=1;i<=n;i++)
        {
            for(int j=coins[i-1];j<=amount;j++)
            {
                dp[j]=dp[j]+dp[j-coins[i-1]];
            }        
        }
        return dp[amount];
    }
}

3.组合总和

377. Combination Sum IV (Medium)

题目:

给定一个由正整数组成且不存在重复数字的数组,找出和为给定目标正整数的组合的个数。

示例:

nums = [1, 2, 3]
target = 4

所有可能的组合为:
(1, 1, 1, 1)
(1, 1, 2)
(1, 2, 1)
(1, 3)
(2, 1, 1)
(2, 2)
(3, 1)

请注意,顺序不同的序列被视作不同的组合。

因此输出为 7。

进阶:
如果给定的数组中含有负数会怎么样?
问题会产生什么变化?
我们需要在题目中添加什么限制来允许负数的出现?

思路:是一个有顺序的完全背包问题,这个之前没有见过,补充一下.在leetcode中的讨论里面有大神说,这个一般的背包问题是物品循环在外循环,背包的重量部分在内循环;但是一旦涉及到物品顺序的问题时,只需要将背包的重量部分放在外循环,内循环是物品的循环就可以了。还要注意的是这里有一个将数组先排序的操作。

代码:

public int combinationSum4(int[] nums, int target) {
if (nums == null || nums.length == 0) {
return 0;
}
int[] maximum = new int[target + 1];
maximum[0] = 1;
Arrays.sort(nums);
for (int i = 1; i <= target; i++) {
for (int j = 0; j < nums.length && nums[j] <= i; j++) {
maximum[i] += maximum[i - nums[j]];
}
}
return maximum[target];
}

 

标签:背包,硬币,int,coins,笔记,amount,总金额,leetcode,dp
来源: https://blog.csdn.net/chenxy132/article/details/92381379

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有