1. 程式人生 > >leetcode-零錢兌換—int溢位

leetcode-零錢兌換—int溢位

零錢兌換 給定不同面額的硬幣 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之間建立一個下標索引,dp表示錢數所需要的最少硬幣數量

首先對已有硬幣進行標記,下標都為1。同時注意:當硬幣的面值大於amount時,將不會被標記。

開始從1遍歷至amount。 

如果當前遍歷的面值不能用硬幣湊出,那麼就跳出,說明無法取到這個面值。比如{2,5,10}  永遠無法取到1,3,7,9。這些都是不需要判斷的。

遍歷的面值再加上硬幣的面值,dp[i+coins[j]]表示當前面值所需最小硬幣數量

需要新增如下幾個判斷條件:

1.遍歷的錢數i+coins[j]一定要小於amount。

2.當前所需硬幣數比原來需要的硬幣數量更少,那麼更新dp。

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]; } }
零錢兌換 給定不同面額的硬幣 coins 和一個總金額 amount。編寫一個函式來計算可以湊成總金額所需的最少的硬幣個數。如果沒有任何一種硬幣組合能組成總金額,返回 -1 示例 1: 輸入: coins = [1, 2, 5], amount = 11輸出: 3 解釋: 11 = 5 + 5 + 1 示例 2: 輸入: coins = [2], amount = 3輸出: -1 說明: 你可以認為每種硬幣的數量是無限的。 問題:輸入{1,2147483647}; 將導致陣列下標越界