返回n个数组的所有可能的排列和数字组合,其总和小于m且大于r

时间:2016-11-22 11:45:16

标签: arrays algorithm

我有两个数组:

array1: [0 1 2 3]
array2: [0 1 2 3 4 5 6 7]
array3: [0 1 2 3 4 5]

我想从每个数组中找到组合,例如每个数组中的1个元素,以便sum >= m eg.3和sum <=r例如。 6

Example:
array1  array2  array3 elements
1          1    1       (sum is 3)
1          5    0       (sum is 6)

1          6     1       (wrong result sum is greater than 6)

提前致谢。

我不明白如何解决这个问题。伪代码将非常有用。

2 个答案:

答案 0 :(得分:0)

让N = 3个排序的数组A(size = p),B(size = q)和C(size = r)。

选择一个数字说X并尝试找到N = 3个数字x1 + x2 + x3的总和 这样X = x1 + x2 + x3。查找x1,x2和x3可以使用动态编程完成。

现在,

考虑序列ABC并使用二进制搜索在数组A中找到x1,在数组B中找到x2,在数组C中找到x3。

考虑序列ACB并使用二进制搜索在数组A中找到x1,在数组C中找到x2,在数组B中找到x3。

考虑序列BAC并使用二进制搜索来查找数组B中的x1,数组A中的x2和数组C中的x3。

你会发现有N!这些序列的数量。

您将被要求对所有X重复上述过程,使得[m]&lt; = [X]&lt; = [r]。

总复杂度为(r - m + 1)*(N!)*((log p)+(log q)+(log r))。

Total Complexity不包括动态编程部分。

答案 1 :(得分:0)

正如我在评论中提到的那样;与蛮力相比,在JS中通过动态编程方法,您可以更快地得到结果,例如总共大约10ms的测试用例,如下所示;

&#13;
&#13;
function getCombos(arr,n,m){

  function getBinaryMap(d){
    return Array(a.length).fill()
                          .reduce((p,c,i) => p.concat(d >> i & 1),[]);
  }

  var a = arr.reduce((p,c) => p.concat(c.filter(e => e !== 0 && e <= m)),[]);
      t = [0],
      r = [];
  a.forEach(e => t = t.concat(t.map((f,i) => (f + e >= n && f + e <= m && r.push(getBinaryMap(t.length + i)), f + e))));
  return r.map(e => e.reduce((p,c,i) => c ? p.concat(a[i]) : p,[]));;
}

var arrays = [[0, 1, 2, 3],[0, 1, 2, 3, 4, 5, 6, 7],[0, 1, 2, 3, 4, 5]];
    result = getCombos(arrays,3,6);

console.log(JSON.stringify(result));
&#13;
&#13;
&#13;