Problem overview
The function sum_of_squares receives a non-negative integer n and returns 1² + 2² + 3² + ... + n². For n = 3 the answer is 1 + 4 + 9 = 14. For n = 0 there are no terms, so the answer is 0.
Approach
The sum is built one term at a time. A variable called sum starts at 0, which means nothing has been added yet. A loop then visits each number i from 1 to n, and each pass adds the square of i to sum. When the loop ends, sum holds the answer and the function returns it.
For n = 3 the variable goes through these values:
- Before the loop:
sumis 0. - With
i = 1:sumbecomes 0 + 1 = 1. - With
i = 2: it becomes 1 + 4 = 5. - With
i = 3: it becomes 5 + 9 = 14.
There is also a closed-form formula, n * (n + 1) * (2 * n + 1) / 6, which gives the same result without a loop. This lesson practises the loop, so it builds the sum term by term.
Step by step
- Declare the accumulator. Write
let mut sum = 0;. It needsmutbecause the loop changes it. Rust infers the typei32from the function's return type, so no annotation is needed. - Loop from 1 to
ninclusive. Use the range1..=n. The plain range1..nwould stop atn - 1and leave out the last square. - Add each square. Inside the loop,
sum += i * i;multipliesiby itself and adds the product. - Return the total after the loop has finished.
The solution in Rust
impl Solution {
fn sum_of_squares(n: i32) -> i32 {
let mut sum = 0;
for i in 1..=n {
sum += i * i;
}
return sum;
}
}
Some Rust details here:
- Inclusive range.
1..=nincludesn. Whennis 0, the range is empty and the loop body never runs, so the function returns 0, which is correct. - Type inference. The literal
0has no type of its own. Becausesumis returned from a function declared to returni32, andicomes from thei32range1..=n, the compiler makes everythingi32. - No exponent operator. Rust has no
**. A square is written asi * i, or asi.pow(2)for an integer. - Immutable by default. Without
mut,sum += i * i;is a compile error.
Complexity
Time: O(n). The loop runs n times and does a constant amount of work on each pass: one multiplication and one addition.
Space: O(1). The function stores only sum and the loop variable.
Edge cases and common mistakes
n = 0. The result is 0, because the loop runs zero times.n = 1. The result is 1.- Stopping one short. With
1..nin place of1..=n,sum_of_squares(3)would return 1 + 4 = 5 instead of 14. - Starting at 0. It is harmless here, since 0 squared adds nothing, but the sum is defined from 1.
- Adding
iinstead ofi * i. That computes the plain sum 1 + 2 + 3 = 6. - Overflow. The result is an
i32, and it only fits up ton = 1860, where the sum is 2,146,682,110, just under the limit of 2,147,483,647. Withn = 1861the true sum is 2,150,145,431, which does not fit. In an optimized build the value wraps around silently and gives a negative number forn = 2000, and in a debug build the same overflow panics.
Testing
n = 3gives 14.n = 0gives 0.n = 1gives 1.n = 2gives 5.n = 10gives 385.n = 100gives 338350.
