返回課程

將所有數字加總至給定數字

重要性:5

撰寫一個函式 sumTo(n) 來計算數字 1 + 2 + ... + n 的總和。

例如

sumTo(1) = 1
sumTo(2) = 2 + 1 = 3
sumTo(3) = 3 + 2 + 1 = 6
sumTo(4) = 4 + 3 + 2 + 1 = 10
...
sumTo(100) = 100 + 99 + ... + 2 + 1 = 5050

提出 3 種解決方案變體

  1. 使用 for 迴圈。
  2. 使用遞迴,因為 sumTo(n) = n + sumTo(n-1),其中 n > 1
  3. 使用 等差數列 公式。

結果範例

function sumTo(n) { /*... your code ... */ }

alert( sumTo(100) ); // 5050

附註:哪個解法變體最快?哪個最慢?為什麼?

再附註:我們可以使用遞迴來計算 sumTo(100000) 嗎?

使用迴圈的解法

function sumTo(n) {
  let sum = 0;
  for (let i = 1; i <= n; i++) {
    sum += i;
  }
  return sum;
}

alert( sumTo(100) );

使用遞迴的解法

function sumTo(n) {
  if (n == 1) return 1;
  return n + sumTo(n - 1);
}

alert( sumTo(100) );

使用公式的解法:sumTo(n) = n*(n+1)/2

function sumTo(n) {
  return n * (n + 1) / 2;
}

alert( sumTo(100) );

附註:當然,公式是速度最快的解法。它只對任何數字 n 使用 3 個運算。數學很有用!

迴圈變體在速度方面排名第二。在遞迴和迴圈變體中,我們對相同的數字求和。但是遞迴涉及巢狀呼叫和執行堆疊管理。這也需要資源,因此速度較慢。

再附註:有些引擎支援「尾呼叫」最佳化:如果遞迴呼叫是函式中的最後一個呼叫,沒有執行其他計算,那麼外部函式不需要繼續執行,因此引擎不需要記住其執行內容。這消除了記憶體負擔。但是,如果 JavaScript 引擎不支援尾呼叫最佳化(大多數都不支援),就會發生錯誤:堆疊大小超過最大值,因為堆疊總大小通常有限制。