以下页面包含"子集和"的二维DP解决方案。问题:
https://github.com/mission-peace/interview/blob/master/src/com/interview/dynamic/SubsetSum.java
核心方法:
boolean[][] T = new boolean[input.length + 1][total + 1];
for (int i = 0; i <= input.length; i++) {
T[i][0] = true;
}
for (int i = 1; i <= input.length; i++) {
for (int j = 1; j <= total; j++) {
if (j - input[i - 1] >= 0) {
T[i][j] = T[i - 1][j] || T[i - 1][j - input[i - 1]];
} else {
T[i][j] = T[i-1][j];
}
}
}
return T[input.length][total];
我试图通过用这样的1-D替换2-D阵列来减少空间使用:
boolean[] T = new boolean[sum + 1];
T[0] = true;
for (int i = 1; i <= input.length; i++) {
for (int j = 1; j <= sum; j++) {
if (j - input[i - 1] >= 0) {
T[j] = T[j] | T[j - input[i - 1]]; //not using ||
}
}
}
return T[sum];
我悲惨地失败了:它对任何输入都是真的。有人可以指出问题吗?
答案 0 :(得分:3)
解决方案的拓扑排序不正确。
如果您将第二个循环更改为for (int j = sum; j >= 1; j--)
,它应该可以正常工作。
这是因为当您在第二个循环中向前移动时,您还在考虑由current index i
解决的解决方案,因此在解决方案中多次包含当前元素,而不是仅包含一次。