leetcode零錢兌換

class Solution {

    public int DP(int[] arr , int num){
        int[] dp = new int[num + 1];

        for(int i = 0 ; i < num + 1 ; i++)
            dp[i] = -1;
        dp[0] = 0;

        for(int i = 1 ; i <= num ; i++)
        {
            int min = -1;

            //遍歷已經存在的所有面額 ,減去該面額餘數是否存在dp[i] (i元拼湊出來的最小硬幣數)
            //存在則在該數量之上+1
            //最終求出最小數量
            for(int j = 0 ; j < arr.length ; j++)
            {
                int tmp = i - arr[j];
                if(tmp >= 0 && dp[tmp] != -1)
                {
                    if(min == -1)
                    {
                        min = dp[tmp] + 1;
                    }
                    else
                    {
                        min = Math.min(min,dp[tmp] + 1);
                    }
                }
            }
            dp[i] = min;
        }

        return dp[num];
    }


    

   public int coinChange(int[] coins, int amount) {

        return DP(coins,amount);
    }
}
public static boolean existNum(int[] arr,int num){
        for(int e : arr)
            if(e == num)
                return true;

        return false;
    }

    //這種方式會超時
    public static int DP1(int[] arr , int num){
        int[] dp = new int[num + 1];

        for(int i = 0 ; i < num + 1 ; i++)
            dp[i] = -1;
        dp[0] = 0;
        for(int i = 1 ; i <= num ; i++)
        {
            int min = -1;

            //此方式是在遍歷之前求出來的每一個dp,在此基礎上增加一個硬幣
            for(int j = 0 ; j < i ; j++)
            {
                if(dp[j] != -1)
                {
                    if(existNum(arr, i - j))
                    {
                        if(min == -1)
                        {
                            min = dp[j] + 1;
                        }
                        else
                        {
                            min = Math.min(min,dp[j] + 1);
                        }
                    }
                }
            }
            dp[i] = min;
        }

        return dp[num];

    }

此題目是典型的動態規劃問題。

當我們要湊出n塊錢

我們可以找出 湊出 n - x 元 的最小硬幣數 加上一枚 x 元的硬幣 (硬幣x必須在我們所擁有的面裏面)

此時我們得先求 n -x 元湊出的最小硬幣數,並且對不同x得取值是進行比較得到最小數量

如此循環遞歸下去可能進行了很多此重複得計算而且耗時(比如我們湊出 n - x 可能被計算多次 )

於是我們動態規劃逆向求解我們先求出1塊錢最小數 依次遞增下去 求出n塊錢最小硬幣數(湊不出來時我們令其爲-1)

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章