將所有數字加總至給定數字
重要性: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 種解決方案變體
- 使用 for 迴圈。
- 使用遞迴,因為
sumTo(n) = n + sumTo(n-1)
,其中n > 1
。 - 使用 等差數列 公式。
結果範例
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 引擎不支援尾呼叫最佳化(大多數都不支援),就會發生錯誤:堆疊大小超過最大值,因為堆疊總大小通常有限制。