Problem overview
The function sumOfSquares receives a non-negative integer n and returns 1*1 + 2*2 + ... + n*n. For n = 3 that is 1 + 4 + 9 = 14. For n = 0 there are no terms, so the sum is 0.
Approach: an accumulator and a counter
The terms follow a clear pattern, so a loop can produce them. Keep a variable sum that holds the total so far, starting at 0 because nothing has been added. Let a counter i run from 1 to n, and on each pass add i * i to sum. When the loop ends, sum holds the answer.
For n = 3, the passes go like this: i = 1 makes the sum 1, i = 2 makes it 5, and i = 3 makes it 14.
Step by step
- Declare
sumwith:=and the value 0. Go infers the typeint. - Write the loop. Declare
iwith:=and start it at 1. Keep going whilei <= n, so thatnitself is included, and add 1 each pass withi++. - Add the square. Inside the loop,
sum += i * iadds the current term. - Return
sumafter the loop.
The solution in Go
func sumOfSquares(n int) int {
sum := 0
for i := 1; i <= n; i++ {
sum += i * i
}
return sum
}
Go details:
- No parentheses in the loop header. The three parts are separated by semicolons, and the braces are required.
:=declares,=assigns.sum := 0creates the variable. After that,sum += i * iupdates it. Declaringsuminside the loop would create a fresh variable each pass and leave nothing to return.- No exponent operator. Go has no
**or^for powers, so the square is written asi * i. The standard library functionmath.Powworks onfloat64, which is the wrong tool for exact integer squares. - Typed arithmetic.
iandsumare bothint, so no conversion is needed.
Why the loop starts at 1 and ends at n
The two bounds come straight from the definition of the sum. The first term is 1 squared and the last is n squared, so the counter must take every whole value from 1 to n, and each exactly once. A loop condition of i <= n expresses "up to and including n". When a task names both ends of a range, check each end against the loop header before running the code. Most mistakes in loops like this come from one bound being off by one.
Complexity
Time: O(n). The loop makes exactly n passes, each with one multiplication and one addition.
Space: O(1). Only sum and i are stored. A closed formula, n * (n + 1) * (2 * n + 1) / 6, would give the answer in constant time, but this lesson practises the loop.
Edge cases and common mistakes
- n = 0. The condition
1 <= 0is false at once, the loop never runs, and the function returns 0. - n = 1. One pass adds 1, and the result is 1.
- Using
i < n. That leaves out the last term. Forn = 3it would give 1 + 4 = 5. - Starting at 0. That still gives the right result, because 0 squared is 0, but it adds a pointless pass. The task's sum starts at 1.
- Adding
iinstead ofi * i. That computes 1 + 2 + 3 = 6 forn = 3. - Squaring the running total. Writing
sum = sum * sumor similar squares the wrong thing. Square the counter, and add. - Overflow. The sum grows roughly like
ncubed divided by 3, so a 64-bitintoverflows only fornaround three million. Go wraps silently instead of reporting it.
Testing
sumOfSquares(3)gives14.sumOfSquares(0)gives0.sumOfSquares(1)gives1.sumOfSquares(10)gives385.