硬币面值组合问题

硬币面值组合问题

问题

这个题目说的是,给你一些面值不同的硬币,每一种面值的硬币都有无限多个,现在你要用这些硬币组成一个给定的数值,那么请问,总共有多少种可能的组合方式?

比如说,给你的硬币有 1 分 2 分两种面值,现在你要用它们凑 4 分钱,有以下 3 种组合方式:

4 = 1 + 1 + 1 + 1
4 = 1 + 1 + 2
4 = 2 + 2

因此,要返回的答案是 3。

代码

public class AlgoCasts {

  private int coinCombination(int[] coins, int start, int sum) {
    if (sum == 0) return 1;
    if (sum < 0) return 0;
    int result = 0;
    for (int i = start; i < coins.length; ++i) {
      result += coinCombination(coins, i, sum - coins[i]);
    }
    return result;
  }

  public int numberOfCoinCombinationRecursive(int sum, int[] coins) {
    return coinCombination(coins, 0, sum);
  }

  // Time: O(n*sum), Space: O(n*sum)
  public int numberOfCoinCombinationDP(int sum, int[] coins) {
    int[][] d = new int[coins.length+1][sum+1];
    for (int i = 0; i <= coins.length; ++i) d[i][0] = 1;

    for (int i = 1; i <= coins.length; ++i) {
      for (int j = 1; j <= sum; ++j) {
        int useCurCoin = j >= coins[i-1] ? d[i][j-coins[i-1]] : 0;
        d[i][j] = d[i-1][j] + useCurCoin;
      }
    }
    return d[coins.length][sum];
  }

  // Time: O(n*sum), Space: O(sum)
  public int numberOfCoinCombinationDPOsum(int sum, int[] coins) {
    int[] d = new int[sum+1];
    d[0] = 1;

    for (int i = 1; i <= coins.length; ++i) {
      for (int j = 1; j <= sum; ++j) {
        int useCurCoin = j >= coins[i-1] ? d[j-coins[i-1]] : 0;
        d[j] = d[j] + useCurCoin;
      }
    }
    return d[sum];
  }

}

  转载请注明: ForwardXu 硬币面值组合问题

 上一篇
最小硬币组合 最小硬币组合
最小硬币组合问题 这个题目说的是,给你一些面值不同的硬币,每一种面值的硬币都有无限多个,现在你要用这些硬币组成一个给定的数值,那么请问,最少需要多少个硬币。另外,如果给你的面值无法组成给定数值,就返回 -1。 比如说,给你的硬币有 1 分
2019-01-06
下一篇 
旋转数组 旋转数组
旋转数组问题 这个题目说的是,给你一个数组和一个数字 k,你要把数组右边的数字旋转到数组左边,一次旋转一个数字,共旋转 k 次。 比如说,给你的数组是: 0, 1, 2, 4, 8 给你的数字 k 是 3: k = 3 把数组右边的
2019-01-06
  目录