【问题标题】:Recursion: prefix sums递归:前缀和
【发布时间】:2020-10-03 08:39:27
【问题描述】:

我正在解决 CodeWars kata。

Link to the Kata

这是我的代码:

function partsSums(arr) {
    let bigSum = [];
    if (arr.length == 0) {
        bigSum.push(0);
    }

    while (arr.length >= 1) {
        let sum = arr.reduce((acc, ele) => acc + ele);
        bigSum.push(sum);
        partsSums(arr.shift());
    }

    return bigSum;
}

正确答案应该是:[20, 20, 19, 16, 10, 0]

我的函数返回:[ 20, 20, 19, 16, 10 ]

请指出我的错误或误解。谢谢!

【问题讨论】:

  • 只删除while条件中的"=" -> arr.length > 1
  • 您的递归调用绝对没有任何作用。它得到一个数字而不是一个数组,并且返回被丢弃。问题的“递归”部分有点人为地粘在上面,没有做任何事情。无法直接评论它的唯一原因是因为参数计算将数组缩短了一个。
  • 请包括任务描述以及您为其列出输出的示例输入。链接可能会过期。

标签: javascript arrays algorithm function recursion


【解决方案1】:

问题在于,当您的数组在循环中达到长度 0 时,您实际上并没有将任何内容附加到 bigSum。您可以通过在循环之后显式添加它来做到这一点。

function partsSums(arr) {
    let bigSum = [];

    while (arr.length >= 1) {
        let sum = arr.reduce((acc, ele) => acc + ele);
        bigSum.push(sum);
        partsSums(arr.shift());
    }
    
    bigSum.push(0);

    return bigSum;
}
console.log(partsSums([0, 1, 3, 6, 10]));

【讨论】:

  • 另外partsSums(arr.shift()); 是多余的,可以只替换为arr.shift()
  • 是的,这确实没有有效地使用递归 TBH。
【解决方案2】:

您可以从右侧减少并将值添加到索引零处的值。

function partsSums(arr) {
    return arr.reduceRight((r, value) => [r[0] + value, ...r], [0]);
}

console.log(partsSums([0, 1, 3, 6, 10]));

快速版本

function partsSums(ls) {
    let l = ls.length,
        result = [];

    result[l] = 0;

    while (l--) result[l] = result[l + 1] + ls[l];

    return result;
}

console.log(partsSums([0, 1, 3, 6, 10]));

【讨论】:

    【解决方案3】:

    这是一个实际的递归,因为您已经用它标记了问题:

    function f(A){
      if (!A.length)
        return [0];
      const prev = f(A.slice(1));
      return [A[0] + prev[0], ... prev];
    }
    
    console.log(f([0, 1, 3, 6, 10]));

    【讨论】:

      【解决方案4】:

      for-loop 遍历 end 开始。

      function partsSums(arr) {
          const res = [];
          let sum = 0;
          for (let i = arr.length; i > -1; i--) {
            res[i] = sum += arr[i] || 0;
          }
          return res;
      }
      console.log(partsSums([0, 1, 3, 6, 10]));

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-03-22
        • 1970-01-01
        • 2011-09-02
        • 1970-01-01
        • 2020-08-14
        • 2017-06-28
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多