加减挑战

时间:2019-09-16 02:48:37

标签: javascript algorithm recursion

嗨,我正在尝试解决此递归挑战,有人可以帮我完成它吗?

这是挑战:

  

让函数PlusMinus(num)读取要传递的num参数,该参数将是1个或多个单个数字的组合,并确定是否有可能用加号或减号分隔数字以获取最终表达式等于零。例如:如果num为35132,则可以通过以下方式将数字分开,即3-5 + 1 + 3-2,该表达式等于零。您的程序应返回所用符号的字符串,因此对于本示例,您的程序应返回-++-。如果不可能使数字表达式等于零,则不可能返回字符串。   如果有多种方法可以使最终表达式等于零,请选择一种包含更多负号字符的表达式。例如:如果num是26712,则您的程序应返回-+-而不是+-+-。   示例测试用例:   输入:199   输出:不可能   输入:26712   输出:-+-

这是我尝试过的:

const plusMinus = (num) => {
  let arr = num.toString().split('').map(num => parseInt(num));
  
  return plusMinusRec(arr, 0);

  function plusMinusRec(arr, target){
    if(arr.length == 1){
      if(arr[0] == target){
        return  ""
      } else {
        return "not possible";
      } 
    }

    let s1 = plusMinusRec(arr.slice(1), arr[0]);
    if(s1 != "not possible"){
      return "-" + s1;
    }
    let s2 = plusMinusRec(arr.slice(1), arr[0] * -1);
    if(s2 != "not possible"){
      return "+" + s2;
    }
    return "not possible";
  }  
}

plusMinus(35132);

2 个答案:

答案 0 :(得分:2)

当您更深入地进行递归调用时,我认为您没有跟踪总和。对于每个后续递归调用,您可以将+arr[0]-arr[0]作为target,到目前为止,这并未考虑到总和。

但是使用这种回溯方法,您有正确的想法。如果将“到目前为止的总和”传递给每个后续调用,则可以在最后检查总数是否为0,并将该路径采用的正负组合添加到可能的组合列表中。最后,您可以退回最多的组合。

function PlusMinus(num) {
  let arr = num.split('').map(num => parseInt(num));
  let possibilities = [];

  const traverse = ([d, ...rest], combination, sum) => {
    if (rest.length === 0) {
      if (sum + d === 0) possibilities.push(combination + '+');
      if (sum - d === 0) possibilities.push(combination + '-');
    } else {
      traverse(rest, combination + '+', sum + d);
      traverse(rest, combination + '-', sum - d);
    }
  }

  const maxMinuses = (combinations) => {
    return combinations.reduce((acc, curr) => [...acc].filter(c => c === '-').length > [...curr].filter(c => c === '-').length ? acc : curr);
  }

  traverse(arr.slice(1), '', arr[0]);
  return possibilities.length ? maxMinuses(possibilities) : 'not possible';
}

console.log(PlusMinus('35132'));
console.log(PlusMinus('199'));
console.log(PlusMinus('26712'));

答案 1 :(得分:0)

由于先前的回答,我改进了代码。

这是带有修复程序的代码:

const plusMinus = (num) => {
  let arr = num.toString().split('').map(num => parseInt(num));

  if(arr.length < 2){
    return "not possible"
  }

  return plusMinusRec(arr.slice(1), arr[0]);

  function plusMinusRec(arr, sum){
    if(arr.length == 1){
      if(sum + arr[0] === 0){
        return "+";
      } else if(sum - arr[0] === 0){
        return "-";
      } else {
      return "not possible";
    }
  }    

  let s2 = plusMinusRec(arr.slice(1), sum - arr[0]);
  if(s2 != "not possible"){
    return "-" + s2;
  }

  let s1 = plusMinusRec(arr.slice(1), sum + arr[0]);
  if(s1 != "not possible"){
    return "+" + s1;
  }

  return "not possible";
  }  
}

plusMinus(35132);