Prefix Sum Array in DSA Rust - Time & Space Complexity
We want to understand how fast we can build and use a prefix sum array.
How does the time needed grow as the input array gets bigger?
Analyze the time complexity of the following code snippet.
fn prefix_sum(arr: &[i32]) -> Vec {
let mut prefix = Vec::with_capacity(arr.len());
let mut sum = 0;
for &num in arr {
sum += num;
prefix.push(sum);
}
prefix
}
This code creates a prefix sum array where each element is the sum of all elements from the start of the input up to and including that position.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: A single loop that goes through each element of the input array once.
- How many times: Exactly once for each element, so n times if the array has n elements.
As the input array grows, the number of steps grows directly with it.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 10 additions and 10 pushes |
| 100 | About 100 additions and 100 pushes |
| 1000 | About 1000 additions and 1000 pushes |
Pattern observation: The work grows evenly as the input size grows; doubling the input doubles the work.
Time Complexity: O(n)
This means the time to build the prefix sum array grows in a straight line with the input size.
[X] Wrong: "Calculating each prefix sum element takes n steps, so total is n squared."
[OK] Correct: Each prefix sum element is built by adding only one new number to the previous sum, so each step is constant time, not repeating the whole sum.
Knowing how prefix sums work and their time cost helps you solve many problems efficiently, showing you understand how to speed up repeated calculations.
"What if we computed prefix sums using nested loops summing from start each time? How would the time complexity change?"
Practice
arr?Solution
Step 1: Understand prefix sum definition
A prefix sum array stores sums of elements from the start of the original array up to each index.Step 2: Compare options with definition
Only An array where each element is the sum of all elements up to that index inarrmatches this definition exactly, describing cumulative sums.Final Answer:
An array where each element is the sum of all elements up to that index inarr-> Option CQuick Check:
Prefix sum = cumulative sum [OK]
- Confusing prefix sum with product or max operations
- Thinking prefix sum stores differences between elements
- Assuming prefix sum stores only the last element's value
prefix from an integer vector arr?Solution
Step 1: Check initialization and first element assignment
let mut prefix = vec![0; arr.len()]; prefix[0] = arr[0]; for i in 1..arr.len() { prefix[i] = prefix[i-1] + arr[i]; } initializes prefix with zeros, sets prefix[0] = arr[0], which is correct.Step 2: Verify loop logic for prefix sums
let mut prefix = vec![0; arr.len()]; prefix[0] = arr[0]; for i in 1..arr.len() { prefix[i] = prefix[i-1] + arr[i]; } loops from 1 to end, adding prefix[i-1] + arr[i], correctly building prefix sums.Final Answer:
let mut prefix = vec![0; arr.len()]; prefix[0] = arr[0]; for i in 1..arr.len() { prefix[i] = prefix[i-1] + arr[i]; } -> Option AQuick Check:
Correct prefix sum loop syntax [OK]
- Using prefix[i+1] inside loop causing out-of-bounds
- Multiplying instead of adding elements
- Not initializing prefix[0] before loop
let arr = vec![2, 4, 6, 8];
let mut prefix = vec![0; arr.len()];
prefix[0] = arr[0];
for i in 1..arr.len() {
prefix[i] = prefix[i-1] + arr[i];
}
println!("{:?}", prefix);Solution
Step 1: Calculate prefix sums step-by-step
prefix[0] = 2; prefix[1] = 2 + 4 = 6; prefix[2] = 6 + 6 = 12; prefix[3] = 12 + 8 = 20.Step 2: Confirm final prefix array
The prefix array is [2, 6, 12, 20], matching [2, 6, 12, 20].Final Answer:
[2, 6, 12, 20] -> Option DQuick Check:
Sum accumulates correctly [OK]
- Printing original array instead of prefix
- Starting prefix sums from zero incorrectly
- Miscomputing sums by skipping elements
let arr = vec![1, 3, 5];
let mut prefix = vec![0; arr.len()];
for i in 0..arr.len() {
prefix[i] = prefix[i-1] + arr[i];
}
println!("{:?}", prefix);Solution
Step 1: Identify cause of out-of-bounds error
At i=0, prefix[i-1] is prefix[-1], which is invalid in Rust and causes panic.Step 2: Fix loop and initialization
Set prefix[0] = arr[0] before loop, then loop from i=1 to arr.len()-1 to safely access prefix[i-1].Final Answer:
The loop starts at 0 but uses prefix[i-1], causing out-of-bounds; start loop at 1 and set prefix[0] = arr[0] -> Option AQuick Check:
Indexing prefix[i-1] at i=0 causes error [OK]
- Starting loop at 0 and accessing prefix[i-1]
- Not initializing prefix[0] before loop
- Ignoring Rust's strict bounds checking
arr = [3, 1, 4, 1, 5, 9, 2]. Using a prefix sum array, how would you efficiently find the sum of elements between indices 2 and 5 (inclusive)?Solution
Step 1: Understand prefix sum usage for range sums
Sum from index l to r = prefix[r] - prefix[l-1], assuming prefix sums start at index 0.Step 2: Apply to given indices 2 to 5
Sum = prefix[5] - prefix[1], since prefix[1] is sum up to index 1.Final Answer:
Calculate prefix sums, then sum = prefix[5] - prefix[1] -> Option BQuick Check:
Range sum = prefix[r] - prefix[l-1] [OK]
- Subtracting prefix[start] instead of prefix[start-1]
- Adding prefix values instead of subtracting
- Using wrong indices for prefix subtraction
Ready to prove it?
Pass the test and this pattern moves unknown
