我无法理解 o(sum) space 复杂度中硬币兑换问题的逻辑
I'm not able to understand logic of coin changing problem in o(sum) space complexity
我在理解硬币找零问题的 O(sum) 复杂度解决方案时遇到困难。
问题陈述是:
给你一组硬币 A。假设你有无限数量的每枚硬币,你可以用多少种方式求和 B。
注意:
组 A 中的硬币将是唯一的。此问题的预期 space 复杂度为 O(B)。
解决方法是:
int count( int S[], int m, int n )
{
int table[n+1];
memset(table, 0, sizeof(table));
table[0] = 1;
for(int i=0; i<m; i++)
for(int j=S[i]; j<=n; j++)
table[j] += table[j-S[i]];
return table[n];
}
谁能给我解释一下这段代码?
首先,让我们确定函数中使用的参数和变量:
参数:
- S包含所有m个硬币的面额。即每个元素包含每个硬币的价值。
- m代表硬币面额的数量。本质上,它是数组 S 的长度。
- n代表要达到的总和B。
变量:
- table:数组 table 中的元素 i 包含给定硬币可以实现总和 i 的方法数。
table[0] = 1
因为只有一种方法可以实现总和为 0(不使用任何硬币)。
- 我遍历每个硬币。
逻辑:
求和的方式数 j = 以下求和:
- 实现 j - S 总和的方法数[0]
- 实现总和 j - S[1] 的方法数
...
- 总和j - S[m-1]的方法数(S[m-1]是第m个硬币的价值)
我没有完全破译或验证其余代码,但我希望这是朝着正确方向迈出的一步。
为代码添加了注释:
#include <stdio.h>
#include <string.h>
int count( int S[], int m, int n )
{
int table[n+1];
memset(table, 0, sizeof(table));
table[0] = 1;
for(int i=0; i<m; i++) // Loop through all of the coins
for(int j=S[i]; j<=n; j++) // Achieve sum j between the value of S[i] and n.
table[j] += table[j-S[i]]; // Add to the number of ways to achieve sum j the number of ways to achieve sum j - S[i]
return table[n];
}
int main() {
int S[] = {1, 2};
int m = 2;
int n = 3;
int c = count(S, m, n);
printf("%d\n", c);
}
备注:
- 代码避免重复:3 = 1+1+1、1+2(如果考虑 2+1,则使用 2 种方式而不是 3 种方式。
- 在价值方面不依赖于硬币的顺序。
我在理解硬币找零问题的 O(sum) 复杂度解决方案时遇到困难。 问题陈述是: 给你一组硬币 A。假设你有无限数量的每枚硬币,你可以用多少种方式求和 B。
注意:
组 A 中的硬币将是唯一的。此问题的预期 space 复杂度为 O(B)。
解决方法是:
int count( int S[], int m, int n )
{
int table[n+1];
memset(table, 0, sizeof(table));
table[0] = 1;
for(int i=0; i<m; i++)
for(int j=S[i]; j<=n; j++)
table[j] += table[j-S[i]];
return table[n];
}
谁能给我解释一下这段代码?
首先,让我们确定函数中使用的参数和变量:
参数:
- S包含所有m个硬币的面额。即每个元素包含每个硬币的价值。
- m代表硬币面额的数量。本质上,它是数组 S 的长度。
- n代表要达到的总和B。
变量:
- table:数组 table 中的元素 i 包含给定硬币可以实现总和 i 的方法数。
table[0] = 1
因为只有一种方法可以实现总和为 0(不使用任何硬币)。 - 我遍历每个硬币。
逻辑: 求和的方式数 j = 以下求和:
- 实现 j - S 总和的方法数[0]
- 实现总和 j - S[1] 的方法数 ...
- 总和j - S[m-1]的方法数(S[m-1]是第m个硬币的价值)
我没有完全破译或验证其余代码,但我希望这是朝着正确方向迈出的一步。
为代码添加了注释:
#include <stdio.h>
#include <string.h>
int count( int S[], int m, int n )
{
int table[n+1];
memset(table, 0, sizeof(table));
table[0] = 1;
for(int i=0; i<m; i++) // Loop through all of the coins
for(int j=S[i]; j<=n; j++) // Achieve sum j between the value of S[i] and n.
table[j] += table[j-S[i]]; // Add to the number of ways to achieve sum j the number of ways to achieve sum j - S[i]
return table[n];
}
int main() {
int S[] = {1, 2};
int m = 2;
int n = 3;
int c = count(S, m, n);
printf("%d\n", c);
}
备注:
- 代码避免重复:3 = 1+1+1、1+2(如果考虑 2+1,则使用 2 种方式而不是 3 种方式。
- 在价值方面不依赖于硬币的顺序。