比方说,我有一个像9这样的设定数字,并且有一个包含#s [1,2,4,6,3,9]
的数组。我想知道哪种循环方法是最好的方法,看看其中一个或多个#加起来是否等于9。我最初的想法是:
我的第一张支票还可以,但是这是我遇到的其他两张支票。对于初学者来说,我知道除使用reduce之外,可能(或可能不需要)递归函数。算法还不是我的强项(但是),但是我渴望并且更愿意改进。任何类型的指导将不胜感激。
const magicNum = 9;
const arr = [10,1,2,4,6,3];
for (let i = 0, arrLength = arr.length; i < arrLength; i++) {
if (arr[i] === magicNum) {
console.log('Number Found!');
continue;
} else if (arr[i] > magicNum) {
continue;
} else if (arr[i] < magicNum) {
// Stuck here
}
}
答案 0 :(得分:1)
您可以采用迭代和递归的方法来查找子集总和。
function getSubsets(array, sum) {
function fork(i = 0, s = 0, t = []) {
if (s === sum) {
result.push(t);
return;
}
if (i === array.length) {
return;
}
if (s + array[i] <= sum) { // shout circuit for positive numbers only
fork(i + 1, s + array[i], t.concat(array[i]));
}
fork(i + 1, s, t);
}
var result = [];
fork();
return result;
}
console.log(getSubsets([10, 1, 2, 4, 6, 3], 9));
.as-console-wrapper { max-height: 100% !important; top: 0; }
要仅获取第一个子集,可以使用找到的第一个值数组退出递归。
function getFirstSubset(array, sum) {
function fork(i = 0, s = 0, t = []) {
if (s === sum) {
return t;
}
if (i === array.length) {
return;
}
return fork(i + 1, s + array[i], t.concat(array[i]))
|| fork(i + 1, s, t);
}
return fork();
}
console.log(getFirstSubset([10, 1, 2, 4, 6, 3], 9));
.as-console-wrapper { max-height: 100% !important; top: 0; }
答案 1 :(得分:0)
这更多是一个动态编程问题。 您可以参考以下内容实现此目的: https://www.geeksforgeeks.org/perfect-sum-problem-print-subsets-given-sum/
您真正需要的是列出数字总和等于给定幻数的数组的所有子集。
编辑: find all subsets that sum to a particular value
的副本从以上帖子中发布@Redu的答案:
function getSummingItems(a,t){
return a.reduce((h,n) => Object.keys(h)
.reduceRight((m,k) => +k+n <= t ? (m[+k+n] = m[+k+n] ? m[+k+n].concat(m[k].map(sa => sa.concat(n)))
: m[k].map(sa => sa.concat(n)),m)
: m, h), {0:[[]]})[t];
}
var arr = Array(20).fill().map((_,i) => i+1), // [1,2,..,20]
tgt = 9,
res = [];
console.time("test");
res = getSummingItems(arr,tgt);
console.timeEnd("test");
console.log("found",res.length,"subsequences summing to",tgt);
console.log(JSON.stringify(res));