遇到一道算法题,题目是将指定数字按照顺序的方式加上加号和减号的到指定结果,请问该问题的解法,是不是采用遍历树的方式来解决该问题?
1、可以使用树遍历的方式回溯,一层层遍历、回溯
2、数学方法,
17+(X1*-1)* 6,(X2*-1)* 25+(X3*-1)* 49+(X4*-1)* 27+(X5*-1)* 65+(X6*-1)* 42+(X7*-1)* 48
解向量X1……X7
给一个JavaScript的实现,从第一个开始,要么加,要么减,不断遍历,看最后的结果是否相等
let arr = [17, 6, 25, 49, 27, 65, 42, 48];
let flag = 99;
let len = arr.length;
//从第一个开始
addOrSub(1, arr[0], []);
function addOrSub(index, sum, res) {
//退出条件,最后一个值
if(index === len){
// 没有相等,直接退出
if(sum !== flag) {
return;
}
//相等,打印结果
let resStr = '';
for(let i = 0; i < len - 1; i++) {
resStr += arr[i] + ' ' + res[i] + ' ';
}
resStr += arr[len-1];
console.log(resStr);
return;
}
index ++ ;
//加
let tempAddSum = sum + arr[index - 1];
//在原来的数组上添加‘+’
let tempAddRes = [...res, '+'];
addOrSub(index, tempAddSum, tempAddRes);
//减
let tempSubSum = sum - arr[index - 1];
//在原来的数组上添加‘-’
let tempSubRes = [...res, '-'];
addOrSub(index, tempSubSum, tempSubRes);
};
最后结果:
17 + 6 + 25 + 49 + 27 + 65 - 42 - 48
17 + 6 - 25 + 49 + 27 - 65 + 42 + 48
是需要穷举遍历,但不一定要用递归树遍历。
你的问题只有加、减两种运算符,正好可以用二进制表示。算法可以简化为:
var arr = [17,6,25,49,27,65,42,48];
var l = 1<<(arr.length-1);
for (var j = 0; j < l; j++) {
var str = arr[0];
for (var i = 1; i < arr.length; i++) {
str += "-+"[(j>>i-1)&1] + arr[i];
}
if (eval(str)==99)
console.log(str);
}
结果:
17+6+25+49+27+65-42-48
17+6-25+49+27-65+42+48
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int a[8] = {17,6,25,49,27,65,42,48};
char b[10];
void add(int sum,int i)
{
if(sum == 99 && i==8)
{
printf("%d",a[0]);
for(int k=1;k<i;k++)
printf("%c%d",b[k],a[k]);
printf(" = %d\n",sum);
}
else if(i<8)
{
b[i] = '+';
add(sum+a[i],i+1);
b[i] = '-';
add(sum-a[i],i+1);
}
}
int main()
{
add(a[0],1);
system("pause");
return 0;
}
结果: