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)

 

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