使用Bactracking的子集总和

时间:2018-10-31 19:03:39

标签: javascript backtracking subset-sum recursive-backtracking

我正在尝试使用回溯解决以下问题:

  

让我们说给您一个数字N,您必须找到   以不同的方式将其写为1、3和4的总和。

这是我的尝试:

const backtrack = (array, index, result = [], sum) => {
  if (index >= array.length || sum < 0) {
    return 0;
  }
  if (sum === 0) {
    console.log(result);
    return 1;
  }

  return (
    backtrack(array, index, result.concat(array[index]), sum - array[index]) +
    backtrack(array, index + 1, result, sum)
  );
};

输入

const array = [1, 3, 4];
const index = 0;
const sum = 5;

输出

[ 1, 1, 1, 1, 1 ]
[ 1, 1, 3 ]
[ 1, 4 ]
3

如您所见,输出只有组合数量的一半。

缺少的组合是:

[ 1, 3, 1 ]
[ 3,1,1]
[ 4, 1 ]

我可以推断出为什么会这样,因为使用backtrack(array, index + 1, result, sum)构造了我的右子树 查找索引大于当前元素的元素。有人可以给我提示我需要进行哪些更改才能实现所需的输出吗?

1 个答案:

答案 0 :(得分:2)

尝试一下:

backtrack = (array, index, result = [], remainig) => {
  if (index >= array.length || remainig < 0) {
    return 0;
  }
  if (remainig === 0) {
    console.log(result);
    return 1;
  }
  var sum = 0;
  for (var ind = 0; ind < array.length; ind++) {
    const curr = array[ind];
    sum += backtrack(array, 0, result.concat(curr), remainig - curr);
  }
  return sum;
};

在定义结果列表的第一个元素时,您必须遍历整个数组。