322. Coin Change

-Billy發表於2018-08-08

	int maxVal = 1000000000; // 把非法的值設定為我們期望方向的反方向
	public int search(int idx, int amount, int[] coins)
	{
		if (amount == 0)
			return 0;
		if (amount < 0)
			return maxVal; // 返會非常大的數,表示非法(不可以返回-1)
		if (idx >= coins.length)
			return maxVal; // 返會非常大的數,表示非法(不可以返回-1)
		// 兩種決策,(只使用某一號硬幣,使用其他)
		int a = search(idx, amount-coins[idx], coins) + 1;
		int b = search(idx+1, amount, coins);
		return Math.min(a,b);
	}
	
	 public int coinChange(int[] coins, int amount)
	 {
		 int res =  search(0, amount, coins);
		 if (res < maxVal)
		 {
			 return res;
		 }
		 else
		 {
			 return -1;
		 }
	 }

 記憶化搜尋改進:(還是會超時,因為amount可能會很大)

	 static int[][] f = new int[1000][1000000];
	 int maxVal = 1000000000; // 把非法的值設定為我們期望方向的反方向
         int search(int idx, int amount, int[] coins)
   	 {
   		if (amount == 0)
   			return 0;
   		if (amount < 0)
   			return maxVal; // 返會非常大的數,表示非法(不可以返回-1)
   		if (idx >= coins.length)
   			return maxVal; // 返會非常大的數,表示非法(不可以返回-1)
   		// 兩種決策,(只使用某一號硬幣,使用其他)
   		int a = search(idx, amount-coins[idx], coins) + 1;
   		int b = search(idx+1, amount, coins);
   		f[idx][amount] =  Math.min(a,b);
   		return f[idx][amount];
   	}
   	
   	 public int coinChange(int[] coins, int amount)
   	 {
   		 // 初始化f陣列
   		 for (int i=0; i<1000; i++)
   		 {
   			 for (int j=0; j<1000000; j++)
   			 {
   				 f[i][j] = -1;
   			 }
   		 }
   		 // 搜尋
   		 int res =  search(0, amount, coins);
   		 if (res < maxVal)
   		 {
   			 return res;
   		 }
   		 else
   		 {
   			 return -1;
   		 }
   	 }

改為迭代實現(自底向上計算):

用dp儲存硬幣數量,dp[i] 表示湊齊錢數 i 需要的最少硬幣數,那麼湊齊錢數 amount 最少硬幣數為:

固定錢數為 coins[j] 一枚硬幣,另外的錢數為 amount - coins[j] 它的數量為dp[amount - coins[j]],j 從0遍歷到

coins.length - 1:

    public int coinChange(int[] coins, int amount) {
        int[] dp = new int[amount + 1];
        for (int i = 1; i <= amount; i++) {
            dp[i] = 0x7fffffff;
            for (int j = 0; j < coins.length; j++)
                if (i >= coins[j] && dp[i - coins[j]] != 0x7fffffff)  //①
                    dp[i] = Math.min(dp[i], dp[i - coins[j]] + 1);
        }
        return dp[amount] == 0x7fffffff ? -1 : dp[amount];
    }

 

相關文章