换钱的最小货币数-Java:原问题在动态规划基础上的空间压缩方法

分享一个大牛的人工智能教程。零基础!通俗易懂!风趣幽默!希望你也加入到人工智能的队伍中来!请轻击http://www.captainbed.net

package live.every.day.ProgrammingDesign.CodingInterviewGuide.RecursionAndDynamicPrograming;

/**
 * 换钱的最小货币数
 *
 * 【题目】
 * 给定数组arr,arr中所有的值都为正数且不重复。每个值代表一种面值的货币,每种面值的货币可以使用任意张,再给定一个整数aim
 * 代表要找的钱数,求组成aim的最小货币数。
 *
 * 【补充题目】
 * 给定数组arr,arr中所有的值都为正数。每个值仅代表一张钱的面值,再给定一个整数aim代表要找的钱数,求组成aim的最小货币数。
 *
 * 【难度】
 * 中等
 *
 * 【解答】
 * 原问题在动态规划基础上的空间压缩方法。空间压缩的原理请参考"矩阵的最小路径和"问题,这里不再详述。我们选择生成一个长度为
 * aim+1的动态规划一维数组dp,然后按行来更新dp即可。之所以不选按列更新,是因为根据
 * dp[i][j]=min{dp[i-1][j],dp[i][j-arr[i]]+1}可知,位置(i,j)依赖位置(i-1,j),即往上跳一下的位置,也依赖位置
 * (i,j-arr[i]),即往左跳arr[i]一下的位置,所以按行更新只需要1个一维数组,按列更新需要的一维数组个数就与arr中货币的
 * 最大值有关,如最大的货币为a,说明最差情况下要向左侧跳a下,相应地,就要准备a个一维数组不断地滚动复用,这样实现起来很麻
 * 烦,所以不采用按列更新的方式。具体请参看如下代码中的minCoins2方法,空间压缩之后时间复杂度为O(N*aim),额外空间复杂
 * 度为O(aim)。
 *
 * @author Created by LiveEveryDay
 */
public class ChangeMoneyMinCurrencyNumberSolution2 {

    public static int minCoins2(int[] arr, int aim) {
        if (arr == null || arr.length == 0 || aim < 0) {
            return -1;
        }
        int n = arr.length;
        int max = Integer.MAX_VALUE;
        int[] dp = new int[aim + 1];
        for (int j = 1; j <= aim; j++) {
            dp[j] = max;
            if (j - arr[0] >= 0 && dp[j - arr[0]] != max) {
                dp[j] = dp[j - arr[0]] + 1;
            }
        }
        int left = 0;
        for (int i = 1; i < n; i++) {
            for (int j = 1; j <= aim; j++) {
                left = max;
                if (j - arr[i] >= 0 && dp[j - arr[i]] != max) {
                    left = dp[j - arr[i]] + 1;
                }
                dp[j] = Math.min(left, dp[j]);
            }
        }
        return dp[aim] != max ? dp[aim] : -1;
    }

    public static void main(String[] args) {
        int[] arr = {5, 2, 5, 3};
        int aim = 10;
        System.out.printf("The min currency number is: %d", minCoins2(arr, aim));
    }

}

// ------ Output ------
/*
The min currency number is: 2
*/

你可能感兴趣的:(#,Coding,Interview,Guide,换钱的最小货币数,动态规划基础上的空间压缩方法)