LeetCode

Stella981
• 阅读 593

零钱兑换

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

示例 1:

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

解释: 11 = 5 + 5 + 1

示例 2:

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

说明:

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

问题:输入{1,2147483647};

做题的时候一直遇到一个问题,Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -2147483648

    说明Int溢出了。得到的结果一直是- 2147483647。 因为i+coins[j]=1+2147483647   >=Integer.MAX_VALUE;

解决办法是如果溢出了,if(i+coins[j]<0) break;  

这里便发现了如果溢出,那么一定是用负数表示的。

x = 2147483647

x+1 = -2147483648
x+2 = -2147483647

当最大值加上 1 时,结果反而变成表示范围中最小的值;当最大值加上 2 时,结

果变成表示范围中次小的值,这就是数据类型的溢出。

算法思路:利用动态规划的思想,在1-amount之间建立一个下标索引,nums表示钱数所需要的最少硬币数量

首先对已有硬币进行标记,下标都为1。同时注意:当硬币的面值大于amount时,将不会被标记。

开始从1遍历至amount。 

如果当前遍历的面值不能用硬币凑出,那么就跳出,说明无法取到这个面值。比如{2,5,10}  永远无法取到1,3,7,9。这些都是不需要判断的。

遍历的面值再加上硬币的面值,nums[i+coins[j]]表示当前面值所需最小硬币数量

需要添加如下几个判断条件:

1.遍历的钱数i+coins[j]一定要小于amount。

2.当前所需硬币数比原来需要的硬币数量更少,那么更新nums数组。

class Solution {
    public int coinChange(int[] coins, int amount) {
       if(amount==0)return 0;
        long[] nums=new long[amount+1];
      for(int i=0;i<coins.length;i++){
          if(coins[i]<=amount)nums[coins[i]]=1;
      }
        for(int i=1;i<=amount;i++){
            if(nums[i]==0)continue;
            for(int j=0;j<coins.length;j++){
            int  temp=i+coins[j];
               if(temp<0) break;        //这里在验证{1,2147483647} 反复出现了错误,因为i+coins[j]已经溢出,溢出是用-22147483647表示,溢出则跳出循环
                if(temp<=amount&&(nums[temp]==0||1+nums[i]<nums[temp]))nums[temp]=1+nums[i];
            }
        }
        if(nums[amount]==0)return -1;//这里如果凑不出amount的面值,那么就不需要判断了。
        return nums[amount];
    }
}
点赞
收藏
评论区
推荐文章
孤心独饮 孤心独饮
3年前
从零开始刷力扣(一)——485:最大连续1的个数
分类:数组的遍历题目描述:给定一个二进制数组,计算其中最大连续1的个数。示例1:输入:1,1,0,1,1,1输出:3解释:开头的两位和最后的三位都是连续1,所以最大连续1的个数是3.思路初始化count和maxCount,然后遍历数组,遇见1则count,并且更新与maxCount比较,若比maxCount更大,则更新m
Kubrnete Kubrnete
3年前
动态规划之马拉车算法
问题描述:给定一个字符串,你的任务是计算这个字符串中有多少个回文子串。具有不同开始位置或结束位置的子串,即使是由相同的字符组成,也会被视作不同的子串。如"abc"有三个回文子串‘a','b','c'.示例1:输入:"abc"输出:3解释:三个回文子串:"a","b","c"示例2:输入:"aaa"输出
Stella981 Stella981
3年前
279. 完全平方数 leetcode JAVA
题目:给定正整数 _n_,找到若干个完全平方数(比如 1,4,9,16,...)使得它们的和等于_n_。你需要让组成和的完全平方数的个数最少。示例 1:输入:_n_12输出:3解释:12444.示例2:输入:_n_13输出:2解释:134
Stella981 Stella981
3年前
LeetCode(94):二叉树的中序遍历
Medium!题目描述:给定一个二叉树,返回它的_中序_遍历。示例:输入:1,null,2,31\2/3输出:1,3,2进阶: 递归算法很简单,你可以通过迭代算法完成吗?解题思路:
Stella981 Stella981
3年前
LeetCode 69 题
1.题目要求实现 intsqrt(intx) 函数。计算并返回 _x_ 的平方根,其中 _x_ 是非负整数。由于返回类型是整数,结果只保留整数的部分,小数部分将被舍去。示例1:输入:4输出:2示例2:输入:8输出:2说
Wesley13 Wesley13
3年前
83. 删除排序链表中的重复元素
题目描述题目地址:https://leetcodecn.com/problems/removeduplicatesfromsortedlist/给定一个排序链表,删除所有重复的元素,使得每个元素只出现一次。示例1:输入:112输出:12示例 2:输入:11233输出:
Stella981 Stella981
3年前
LeetCode:(14. 最长公共前缀!!!!!)
题目:14\.最长公共前缀编写一个函数来查找字符串数组中的最长公共前缀。如果不存在公共前缀,返回空字符串“”。示例1:输入:\“flower”,“flow”,“flight”\输出:“fl”示例2:输入:\“dog”,“racecar”,“car”\输出:“”
Stella981 Stella981
3年前
LeetCode459. 重复的子字符串
1.问题描述给定一个非空的字符串,判断它是否可以由它的一个子串重复多次构成。给定的字符串只含有小写英文字母,并且长度不超过10000。示例1:输入:“abab”输出:True解释:可由子字符串“ab”重复两次构成。示例2:输入:“aba”输出:Fal
Stella981 Stella981
3年前
LeetCode:283.移动零——简单
题目:283.移动零:给定一个数组nums,编写一个函数将所有0移动到数组的末尾,同时保持非零元素的相对顺序。示例:输入:0,1,0,3,12输出:1,3,12,0,0说明:1.必须在原数组上操作,不能拷贝额外的数组。2.尽量减少操作
菜园前端 菜园前端
1年前
什么是贪心算法?
原文链接:什么是贪心算法?贪心算法是算法设计的一种方法。期盼通过每个阶段的局部最优选择,从而达到全局的最优。但结果不一定是最优的。基础案例场景一零钱兑换现有硬币1元、2元、5元,需要用最少的硬币数量凑够11元。利用贪心算法实现,优先考虑最好的结果就是面值为