Javascript 返回数组中总和小于或等于n的所有可能的数字组合
也许我遗漏了一些正确的答案,但你明白了。真想知道如何解决这个问题 试试这个:Javascript 返回数组中总和小于或等于n的所有可能的数字组合,javascript,combinations,permutation,Javascript,Combinations,Permutation,也许我遗漏了一些正确的答案,但你明白了。真想知道如何解决这个问题 试试这个: var a = [1,3,6,10,-1]; function combinations(array, n) { } combinations(a, 9) // should return... [[1], [3], [6], [-1], [1,3], [1,6], [1,-1], [3,6], [3,-1], [6, -1], [10, -1], [1,3,-1], [3,6,-1], [1,6,-1], [1,3
var a = [1,3,6,10,-1];
function combinations(array, n) {
}
combinations(a, 9) // should return...
[[1], [3], [6], [-1], [1,3], [1,6], [1,-1], [3,6], [3,-1], [6, -1], [10, -1], [1,3,-1], [3,6,-1], [1,6,-1], [1,3,6,-1]]
编辑:在到期时给予信用。。借用了这一逻辑的大部分 强力O(N*2N)解,其中
N=a.length<31
这使用索引i
作为位字段,以过滤每个迭代中a
的元素到子列表中
[[1], [3], [6], [-1], [1, 3], [1, 6], [1, -1], [3, 6], [3, -1], [6, -1], [10, -1], [1, 3, -1], [1, 6, -1], [3, 6, -1], [1, 3, 6, -1]]
var a=[1,3,6,10,-1];
函数组合(数组,n){
var列表=[],M=1k&1});
如果(sublist.reduce(function(p,c){return p+c},0),我想说这里的问题是取数组的幂集,并将其过滤到只有和大于某个数的元素
一个集合的幂集是该集合的所有子集的集合。(如果快五倍,你就会成为数学家)
例如,[1]
的幂集是[[],[1]]
,[1,2]
的幂集是[],[1],[2],[1,2]]
var lastElement = arr.pop();
首先,我将定义一个powerSet
函数,如下所示:
var a = [1,3,6,10,-1];
function combinations(array, n) {
var lists = [], M = 1<<array.length;
for( var i = 1 ; i < M ; ++i ) {
var sublist = array.filter(function(c,k){return i>>k & 1});
if( sublist.reduce(function(p,c){return p+c},0) <= n )
lists.push(sublist);
}
return lists;
}
console.log(JSON.stringify(combinations(a,9)));
如果传入至少包含一个元素的集合,则powerSet
函数将从删除最后一个元素开始。例如,如果在[1,2]
上调用powerSet
,变量lastElement
将设置为2
,而arr
将设置为[1]
var powerSet = function (arr) {
if(arr.length === 0) {
return [[]];
}
然后,powerSet
函数递归调用自身以获取列表中“其余”部分的电源集。如果您传入了[1,2]
,则restpowset
将被分配给powerSet([1])
,即[[],[1]
var lastElement = arr.pop();
我们定义了一个变量,它将保存传入内容的幂集,这里[1,2]
var restPowerset = powerSet(arr);
我们在restpowset
中循环遍历每个集合
var powerset = [];
如果将元素2
添加到[1]
的任何子集,则该元素也是[1,2]
的子集,因此我们将其添加到列表中。[2]
和[1,2]
都是[1,2]
的子集
for(var i = 0; i < restPowerset.length; i++) {
var set = restPowerset[i];
powerset.push(set);
仅此而已。此时,变量powerset
是[[],[2],[1],[1,2]]]
。返回它
set = set.slice(); // copy the array
set.push(lastElement); // add the element
powerset.push(set);
不玩看起来很有趣,以下是我所拥有的
Javascript
}
return powerset;
};
/**
* Get an array of all the possible combinations
* of x items. Combinations are represented as binary.
* @param {Number} x - example 2
* @return {String[]} - example ['00', '01', '10', '11']
*/
function getCombinationsOfXItems(x) {
var allOn = '',
numCombos = 0,
i = 0,
combos = [];
// find upper limit
while (allOn.length < x) {
allOn += 1;
}
// number of possible combinations
numCombos = parseInt(allOn, 2) + 1;
// generate the combos
while(i < numCombos) {
combos.push(pad(toBase2(i++), allOn.length));
}
return combos;
}
/**
* Pad a string with leading zeros.
* @param {String} x - example '100'
* @param {Number} length - example 6
* @return {String} - example '000100'
*/
function pad(x, length) {
while (x.length < length) {
x = 0 + x;
}
return x;
}
/**
* Get a number as a binary string.
* @param {Number} x - example 3
* @return {String} - example '11'
*/
function toBase2(x) {
return x.toString(2);
}
/**
* Given an array and a map of its items as a binary string,
* return the items identified by 1.
* @param {Array} arr - example [1,2,3]
* @param {String} binary - example '101'
* @return {Array} - example [1,3]
*/
function pluckFromArrayByBinary(arr, binary) {
var plucked = [],
i = 0,
max = binary.length;
for (; i < max; i++) {
if (binary[i] === '1') {
plucked.push(arr[i]);
}
}
return plucked;
}
/**
* Given an array, return a multi-dimensional
* array of all the combinations of its items.
* @param {Array} - example [1, 2];
* @return {Array[]} - [ [1], [1, 2], [2] ]
*/
function getCombosOfArrayItems(arr) {
var comboMaps = getCombinationsOfXItems(arr.length),
combos = [];
// remove the "all off" combo (ex: '00000')
comboMaps.shift();
for (var i = 0; i < comboMaps.length; i++) {
combos.push(pluckFromArrayByBinary(arr, comboMaps[i]));
}
return combos;
}
/**
* Return all possible combinations of numbers in an
* array whose sum is less than or equal to n
* @param {Number[]} arr
* @param {Number} x
* return {Number[]} - stringified for readability
*/
function combinations(arr, x) {
var combos = getCombosOfArrayItems(arr),
i = 0,
max = combos.length,
combo;
for (; i < max; i++) {
if (sumArray(combos[i]) > x) {
combos.splice(i, 1);
i--;
max--;
}
}
return JSON.stringify(combos);
}
/**
* Return the sum of an array of numbers.
* @param {Number[]} arr
* @return {Number}
*/
function sumArray(arr) {
var sum = 0,
i = 0,
max = arr.length;
for (; i < max; i++) {
sum += arr[i];
}
return sum;
}
console.log(combinations([1, 3, 6, 10, -1], 9));
在
尽管@jcarcenter solutions给出了一个模棱两可的定义,但这其中还是有很多
在现代浏览器上,您可以使用for
intead of,
从这个解决方案中榨取更多,因为它们对for
进行了高度优化。通过索引分配而不是推送
也可以提高性能
如果我觉得无聊的话,最好扩展性能测试以包含更多的测试集。类似于Matt的答案,但使用Array.filter()和Array.reduce()来填充一个打孔。在本例中,mask
变量从1增加到32-1(因为数组长度为5,count
=1i)&1==1}
var sum=函数(a,b){返回a+b}
用于(掩码=1;掩码<计数;++掩码){
置换.推(数组.过滤器(不可测))
}
返回置换。filter(函数(p){return p.reduce(sum)这里的简洁性非常神秘。一些描述性函数如何
该方法使用二进制创建所有可能组合的映射。然后映射用于从数组中提取项目。提取的项目被求和,仅此而已
产生的组合([1,3,6,10,-1],9)
的结果是:[1]、[10,-1]、[6]、[6,-1]、[3]、[3,-1]、[3,6]、[3,6,-1]、[1,6]、[1,6]、[1,6,-1]、[1,3]、[1,3,6,-1]
var lastElement = arr.pop();
/**
*获取所有可能组合的数组
*共x项。组合表示为二进制。
*@param{Number}x-示例2
*@return{String[]}-示例['00','01','10','11']
*/
函数getCombinationsOfXItems(x){
变量allOn=“”,
numCombos=0,
i=0,
组合=[];
//求上限
while(allOn.length set = set.slice(); // copy the array
set.push(lastElement); // add the element
powerset.push(set);
}
return powerset;
};
function kCombs(set, k) {
var setLength = set.length,
combs = [],
i = 0,
tailLength,
head,
tail,
j,
t,
u;
if (k > 0 && k <= setLength) {
if (k === setLength) {
combs.push(set);
} else if (k === 1) {
while (i < setLength) {
combs.push([set[i]]);
i += 1;
}
} else {
u = k - 1;
setLength = setLength - k + 1;
while (i < setLength) {
t = i + 1;
head = set.slice(i, t);
tail = kCombs(set.slice(t), u);
j = 0;
tailLength = tail.length;
while (j < tailLength) {
combs.push(head.concat(tail[j]));
j += 1;
}
i = t;
}
}
}
return combs;
}
function combinations(array, n) {
var arrayLength = array.length,
combs = [],
combsLength,
results = [],
temp = 0,
current,
currentLength,
i,
j,
k = 1;
while (k <= arrayLength) {
i = 0;
current = kCombs(array, k);
currentLength = current.length;
while (i < currentLength) {
combs.push(current[i]);
i += 1;
}
k += 1;
}
i = 0;
combsLength = combs.length;
while (i < combsLength) {
j = 0;
current = combs[i];
currentLength = current.length;
while (j < currentLength) {
temp += current[j];
j += 1;
}
if (temp <= n) {
results.push(current);
}
temp = 0;
i += 1;
}
return results;
}
var a = [1, 3, 6, 10, -1];
console.log(JSON.stringify(combinations(a, 9)));
[[1],[3],[6],[-1],[1,3],[1,6],[1,-1],[3,6],[3,-1],[6,-1],[10,-1],[1,3,-1],[1,6,-1],[3,6,-1],[1,3,6,-1]]
var a = [1,3,6,10,-1];
function combinations(array, n) {
var mask, len = array.length, count = 1 << len, permutations = [];
var indexVisible = function(v, i) { return ((mask >> i) & 1) == 1 }
var sum = function(a, b) { return a + b }
for (mask = 1; mask < count; ++mask) {
permutations.push(array.filter(indexVisible))
}
return permutations.filter(function(p) { return p.reduce(sum) <= n })
}
console.log(JSON.stringify(combinations(a, 9)));
/**
* Get an array of all the possible combinations
* of x items. Combinations are represented as binary.
* @param {Number} x - example 2
* @return {String[]} - example ['00', '01', '10', '11']
*/
function getCombinationsOfXItems(x) {
var allOn = '',
numCombos = 0,
i = 0,
combos = [];
// find upper limit
while (allOn.length < x) {
allOn += 1;
}
// number of possible combinations
numCombos = parseInt(allOn, 2) + 1;
// generate the combos
while(i < numCombos) {
combos.push(pad(toBase2(i++), allOn.length));
}
return combos;
}
/**
* Pad a string with leading zeros.
* @param {String} x - example '100'
* @param {Number} length - example 6
* @return {String} - example '000100'
*/
function pad(x, length) {
while (x.length < length) {
x = 0 + x;
}
return x;
}
/**
* Get a number as a binary string.
* @param {Number} x - example 3
* @return {String} - example '11'
*/
function toBase2(x) {
return x.toString(2);
}
/**
* Given an array and a map of its items as a binary string,
* return the items identified by 1.
* @param {Array} arr - example [1,2,3]
* @param {String} binary - example '101'
* @return {Array} - example [1,3]
*/
function pluckFromArrayByBinary(arr, binary) {
var plucked = [],
i = 0,
max = binary.length;
for (; i < max; i++) {
if (binary[i] === '1') {
plucked.push(arr[i]);
}
}
return plucked;
}
/**
* Given an array, return a multi-dimensional
* array of all the combinations of its items.
* @param {Array} - example [1, 2];
* @return {Array[]} - [ [1], [1, 2], [2] ]
*/
function getCombosOfArrayItems(arr) {
var comboMaps = getCombinationsOfXItems(arr.length),
combos = [];
// remove the "all off" combo (ex: '00000')
comboMaps.shift();
for (var i = 0; i < comboMaps.length; i++) {
combos.push(pluckFromArrayByBinary(arr, comboMaps[i]));
}
return combos;
}
/**
* Return all possible combinations of numbers in an
* array whose sum is less than or equal to n
* @param {Number[]} arr
* @param {Number} x
* return {Number[]} - stringified for readability
*/
function combinations(arr, x) {
var combos = getCombosOfArrayItems(arr),
i = 0,
max = combos.length,
combo;
for (; i < max; i++) {
if (sumArray(combos[i]) > x) {
combos.splice(i, 1);
i--;
max--;
}
}
return JSON.stringify(combos);
}
/**
* Return the sum of an array of numbers.
* @param {Number[]} arr
* @return {Number}
*/
function sumArray(arr) {
var sum = 0,
i = 0,
max = arr.length;
for (; i < max; i++) {
sum += arr[i];
}
return sum;
}
console.log(combinations([1, 3, 6, 10, -1], 9));
function powerSet(arr) {
var lastElement,
val;
if (!arr.length) {
val = [[]];
} else {
lastElement = arr.pop();
val = powerSet(arr).reduce(function (previous, element) {
previous.push(element);
element = element.slice();
element.push(lastElement);
previous.push(element);
return previous;
}, []);
}
return val;
}
function combinations(array, n) {
return powerSet(array).filter(function (set) {
return set.length && set.reduce(function (previous, element) {
return previous + element;
}, 0) <= n;
});
}
var a = [1, 3, 6, 10, -1];
console.log(JSON.stringify(combinations(a, 9)));
[[-1],[10,-1],[6],[6,-1],[3],[3,-1],[3,6],[3,6,-1],[1],[1,-1],[1,6],[1,6,-1],[1,3],[1,3,-1],[1,3,6,-1]]