这是我为硬币变化挑战找到的正确的复发关系吗?

时间:2016-10-25 17:46:12

标签: algorithm recursion data-structures tree time-complexity

我试图解决"硬币更改问题"我想我已经提出了递归解决方案,但我想验证一下。

作为一个例子,让我们假设我们有便士,镍币和硬币,并试图改变22美分。

C = { 1 = penny, nickle = 5, dime = 10 }
K = 22 

然后进行更改的方式是

f(C,N) = f({1,5,10},22) 
=
  (# of ways to make change with 0 dimes) 
+ (# of ways to make change with 1 dimes) 
+ (# of ways to make change with 2 dimes) 

= f(C\{dime},22-0*10) + f(C\{dime},22-1*10) + f(C\{dime},22-2*10)
= f({1,5},22) + f({1,5},12) + f({1,5},2)

  f({1,5},22) 
= f({1,5}\{nickle},22-0*5) + f({1,5}\{nickle},22-1*5) + f({1,5}\{nickle},22-2*5) + f({1,5}\{nickle},22-3*5) + f({1,5}\{nickle},22-4*5)
= f({1},22) + f({1},17) + f({1},12) + f({1},7) + f({1},2)
= 5

等等。

换句话说,我的算法就像

let f(C,K) be the number of ways to make change for K cents with coins C
and have the following implementation

if(C is empty or K=0)
    return 0
sum = 0
m = C.PopLargest()
A = {0, 1, ..., K / m}
for(i in A)
   sum += f(C,K-i*m)
return sum

如果有任何缺陷?

我想是线性时间。

1 个答案:

答案 0 :(得分:0)

重新考虑你的基本情况:

1. What if K < 0 ? Then no solution exists. i.e. No of ways = 0.

2. When K = 0, so there is 1 way to make changes and which is to consider zero elements from array of coin-types. 

3. When coin array is empty then No of ways = 0.

其余逻辑是正确的。但是你认为算法是线性的是完全错误的。

让我们计算复杂性:

  • 弹出最大元素是O(C.length)。但是这一步可以 如果您考虑在开始时对整个数组进行排序,则进行优化。
  • 你的for循环在每次调用中都会运行O(K / C.max)次,并且在每次迭代中都会递归调用函数。

所以如果你为它写了重复。那应该是这样的:

T(N) = O(N) + K*T(N-1)

就N(阵列大小)来说,这将是指数级的。

如果您正在寻求改进,我建议您使用动态编程。