【问题标题】:PlusMinus Challenge加减挑战
【发布时间】:2020-01-16 21:02:26
【问题描述】:

您好,我正在尝试解决这个递归挑战,谁能帮我完成它吗?

这是挑战:

让函数 PlusMinus(num) 读取传递的 num 参数,该参数将是 1 个或多个单个数字的组合,并确定是否可以用加号或减号分隔数字以获得最终表达式等于零。例如:如果 num 是 35132,那么可以按以下方式分隔数字,3 - 5 + 1 + 3 - 2,这个表达式等于 0。您的程序应返回您使用的符号字符串,因此对于此示例,您的程序应返回 -++-。如果无法使数字表达式为零,则返回不可能的字符串。 如果有多种方法可以使最终表达式等于 0,请选择包含更多减号字符的方法。例如:如果 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);

【问题讨论】:

    标签: javascript algorithm recursion


    【解决方案1】:

    我认为您在深入递归调用时不会跟踪总和。对于每个后续的递归调用,您要么将 +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'));

    【讨论】:

      【解决方案2】:

      感谢先前答案的建议,我改进了我的代码。

      这是带有修复的代码:

      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);

      【讨论】: