我有一个正整数列表,例如15, 29, 110
,以及目标44
。我试图找到所有可能的组合,它们总和到目标但重要的是,集合中的数字可以多次使用,例如。
Target = 44
Result = 1x15, 1x29
Target = 307
Result = 2x110, 3x29
我找到了一个动态编程解决方案,当组合不超过每个数字的一个时,它可以工作。所以Target 44可以工作但不是我的307示例(返回Not Found)。
如何重复使用倍数或数字?
function subset(people, min, max)
{
var subsets = [];
subsets[0] = '';
for (var person in people)
{
for (var s = min-1; s >= 0; --s)
{
if (s in subsets)
{
var sum = s + people[person];
if (!(sum in subsets))
{
subsets[sum] = subsets[s] + ' ' + person;
if (sum >= min && sum <= max)
{
return subsets[sum];
}
}
}
}
}
return 'Not found';
}
var p = {
optionA:15,
optionB:29,
optionC:110
};
var qty = 307;
console.log(subset(p, qty, qty));
答案 0 :(得分:0)
尝试这种递归解决方案:
function subset(people, min, max) {
const pairs = Object.entries(people),
results = [],
getSum = multiplications => multiplications.reduce((sum, multiplicator, position) =>
sum + pairs[position][1] * multiplicator, 0),
formatResult = result => result.map(multiplications =>
multiplications.reduce((res, multiplicator, position) =>
(multiplicator > 0 ? res.push(`${multiplicator}x${pairs[position][1]}`) :
res, res), []));
function findSums(multiplications, position) {
let s;
while((s = getSum(multiplications)) <= max) {
if (s >= min) {
results.push([...multiplications]);
}
if (position < pairs.length - 1) {
const m = [...multiplications],
nextPosition = position + 1;
m[nextPosition]++;
findSums(m, nextPosition);
}
multiplications[position]++;
}
}
findSums(pairs.map(_ => 0), 0);
return results.length > 0 ? formatResult(results) : "Not found";
}
var p = {
optionA:15,
optionB:29,
optionC:110
};
var qty = 307;
console.log(subset(p, qty, qty));
&#13;
答案 1 :(得分:0)
以这种方式更改第二个循环:
for (var s = 0; s <= wantedSum - people[person] ; s++)
使用此方法填充subsets[]
array \ list的所有条目,其中index是people[person]
的倍数(而不是单个条目)。例如,对于值3,您将填写3,6,9,12 ...个条目。