Sum is to be calculated for the numbers in between

2019-02-20 22:38发布

问题:

It seems that the compiler is not going into the for loop.The sum of the array is to calculated.SumAll([1,4]) should return 10(1+2+3+4) as output.

function sumAll(arr) {
      //return Math.max.apply(Math,arr);
      //return Math.min.apply(Math,arr);

        //  return "0";
        var sum=arr.reduce(function(a,b){
          for(var i=Math.min.apply(Math,arr);i<=Math.max.apply(Math,arr);i++){
         return a+b;
        }
        },0);
      //return sum;
    }

    sumAll([1, 4]);

回答1:

You could use directly the values from the array, without reduce.

function sumAll(arr) {
    var i, sum = 0;
    for (i = Math.min.apply(null, arr); i <= Math.max.apply(null, arr); i++) {
        sum += i;
    }
    return sum;
}

console.log(sumAll([1, 4]));
console.log(sumAll([1, 3, 9]));



回答2:

You don't need a reduce because you don't have an array to reduce. You can however keep the for loop and accumulate the sum by adding i to sum on each iteration. The problem was that you:

  • Used and unnecessary reduce
  • was return ing immediately out of the for loop, so no accumulation of sum was occuring.

Here's what the code should look like:

function sumAll(arr) {

  var sum = 0;
  for (var i = Math.min.apply(Math, arr); i <= Math.max.apply(Math, arr); i++) {
    sum += i;
  }

  return sum;
}

console.log(sumAll([1, 4]));



回答3:

It seems no one wants to use the formula for the sum of the first N natural numbers:

function sumAll(arr) { 
   let start = Math.min.apply(Math, arr); 
   let end = Math.max.apply(Math, arr);  
   return (end * (end+1) - start * (start-1) ) / 2;
}


回答4:

You can try something like this:

Note: your array has limits of range, so you should use these values for loop and use i to calculate sum.

Sample

For loop

function getSumOfRange(arr){
  var min = Math.min.apply(null, arr)
  var max = Math.max.apply(null, arr);
  
  var sum = 0;
  for(var i=min; i<= max; i++){
    sum+=i;
  }
  return sum;
}

console.log(getSumOfRange([1,4]))

Formula based

function getSumOfRange(arr){
  var min = Math.min.apply(null, arr)
  var max = Math.max.apply(null, arr);
  var diff = (max-min) + 1;
  var sum = (min + max);
  var total = sum * Math.floor(diff/2)
  return diff % 2 === 0 ? total : total + (sum/2);
}

console.log(getSumOfRange([1,4]))
console.log(getSumOfRange([10,40]))


Your Code's explanation

function sumAll(arr) {
  var sum = arr.reduce(function(a, b) {
    // Loop will only run once as you are returning
    for (var i = Math.min.apply(Math, arr); i <= Math.max.apply(Math, arr); i++) {
      // 1st Time: a=0; b=1;
      // 2nd Time: a=1; b=4;
      return a + b;
    }
  }, 0);
   
  // Sum = 5 and not 10;
  
  // You have commented return hence no output is given back.
  //return sum;
}

sumAll([1, 4]);



回答5:

There are 2 ways to do this.

  1. Using the mathematical formula n1 + (n1 + 1) + ... + n2 = n2(n2 + 1) / 2 - n1(n1 - 1) / 2. Time complexity: O(1)
  2. Programmatically. Time complexity: O(n)

Obviously for numbers with large range, the first way is much faster.

function sumAllMath(arr) {
  if (!(Array.isArray(arr) 
      && arr.length === 2
      && typeof arr[0] === 'number'
      && typeof arr[1] === 'number'
      && arr[0] < arr[1])) {
      return;
  }  
  
  var from = arr[0];
  var to = arr[1];
  return ((to * (to + 1)) / 2) - ((from * (from - 1)) / 2);
}

console.log(sumAllMath([1,4]))

function sumAll(arr) {
  if (!(Array.isArray(arr) 
      && arr.length === 2
      && typeof arr[0] === 'number'
      && typeof arr[1] === 'number'
      && arr[0] < arr[1])) {
      return;
  }  
  
  var sum = 0;
  var from = arr[0];
  var to = arr[1];
  while(from <= to) {
    sum += from;
    ++from;
  }
  
  return sum;
}

console.log(sumAll([1,4]))