Kadane's Algorithm Maximum Subarray in DSA Rust - Time & Space Complexity
We want to understand how fast Kadane's Algorithm finds the maximum sum of a continuous subarray.
How does the time needed grow as the input array gets bigger?
Analyze the time complexity of the following code snippet.
fn max_subarray_sum(arr: &[i32]) -> i32 {
let mut max_ending_here = 0;
let mut max_so_far = i32::MIN;
for &x in arr {
max_ending_here = (max_ending_here + x).max(x);
max_so_far = max_so_far.max(max_ending_here);
}
max_so_far
}
This code finds the largest sum of any continuous part of the input array.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: One loop that goes through each element of the array once.
- How many times: Exactly once per element, so n times for an array of size n.
As the array gets bigger, the number of steps grows directly with the number of elements.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 10 steps |
| 100 | About 100 steps |
| 1000 | About 1000 steps |
Pattern observation: The work grows in a straight line with input size; doubling input doubles work.
Time Complexity: O(n)
This means the time to find the maximum subarray sum grows linearly with the size of the input array.
[X] Wrong: "Kadane's Algorithm checks all possible subarrays, so it must be O(n²) or worse."
[OK] Correct: Kadane's cleverly keeps track of sums as it goes, so it only needs one pass through the array, not checking every subarray separately.
Understanding Kadane's Algorithm shows you can find efficient solutions by avoiding repeated work, a key skill in coding challenges and real projects.
"What if we wanted to find the maximum subarray sum but only for subarrays of a fixed length k? How would the time complexity change?"
Practice
Solution
Step 1: Understand the problem Kadane's Algorithm solves
Kadane's Algorithm is designed to find the maximum sum of a contiguous subarray within a one-dimensional array of numbers.Step 2: Differentiate from other array operations
It does not find minimum elements, total sums, or products, but specifically the maximum sum of a continuous segment.Final Answer:
The maximum sum of a contiguous subarray -> Option AQuick Check:
Maximum subarray sum = maximum sum of contiguous elements [OK]
- Confusing maximum sum with maximum product
- Thinking it finds minimum elements
- Assuming it sums all elements
Solution
Step 1: Identify correct initialization for Kadane's variables
max_so_far should start at the smallest possible integer (i32::MIN) to handle all negative arrays; max_ending_here starts at 0 to accumulate sums.Step 2: Check other options for correctness
Options B and C incorrectly initialize variables, and D uses i32::MAX which is incorrect for max_so_far.Final Answer:
let mut max_so_far = i32::MIN; let mut max_ending_here = 0; -> Option CQuick Check:
Initialize max_so_far to smallest int, max_ending_here to 0 [OK]
- Initializing max_so_far to 0 causes errors with all negative arrays
- Using i32::MAX for max_so_far is wrong
- Not using mutable variables for updates
let nums = vec![4, -1, 2, 1, -5, 4];
let mut max_so_far = i32::MIN;
let mut max_ending_here = 0;
for &x in &nums {
max_ending_here = (max_ending_here + x).max(x);
max_so_far = max_so_far.max(max_ending_here);
}
println!("{}", max_so_far);Solution
Step 1: Trace max_ending_here and max_so_far through iterations
Start: max_so_far = i32::MIN, max_ending_here = 0 - Add 4: max_ending_here = max(0+4,4)=4; max_so_far = max(i32::MIN,4)=4 - Add -1: max_ending_here = max(4-1,-1)=3; max_so_far = max(4,3)=4 - Add 2: max_ending_here = max(3+2,2)=5; max_so_far = max(4,5)=5 - Add 1: max_ending_here = max(5+1,1)=6; max_so_far = max(5,6)=6 - Add -5: max_ending_here = max(6-5,-5)=1; max_so_far = max(6,1)=6 - Add 4: max_ending_here = max(1+4,4)=5; max_so_far = max(6,5)=6Step 2: Identify maximum subarray sum
The maximum sum found is 6.Final Answer:
6 -> Option DQuick Check:
Max subarray sum = 6 [OK]
- Adding all positive numbers ignoring resets
- Miscomputing max_ending_here after negative values
- Choosing wrong max_so_far update
let nums = vec![-2,1,-3,4,-1,2,1,-5,4];
let mut max_so_far = 0;
let mut max_ending_here = 0;
for &x in &nums {
max_ending_here += x;
if max_ending_here < 0 {
max_ending_here = 0;
}
if max_so_far < max_ending_here {
max_so_far = max_ending_here;
}
}
println!("{}", max_so_far);Solution
Step 1: Analyze initialization of max_so_far
max_so_far starts at 0, which fails if all numbers are negative because max_so_far will never update to a negative max subarray sum.Step 2: Confirm correct initialization for negative arrays
max_so_far should start at i32::MIN to correctly track maximum sums even if all are negative.Final Answer:
max_so_far should start at i32::MIN to handle all negative arrays -> Option AQuick Check:
Initialize max_so_far to smallest int for negatives [OK]
- Starting max_so_far at 0 causes wrong max for negative arrays
- Resetting max_ending_here incorrectly
- Ignoring reference iteration is valid in Rust
nums = [-2, -3, 4, -1, -2, 1, 5, -3], what is the maximum subarray sum using Kadane's Algorithm, and which subarray produces it?Solution
Step 1: Calculate max subarray sums step-by-step
Traverse nums: - Start max_so_far = i32::MIN, max_ending_here = 0 - -2: max_ending_here = max(0-2,-2) = -2; max_so_far = -2 - -3: max_ending_here = max(-2-3,-3) = -3; max_so_far = -2 - 4: max_ending_here = max(-3+4,4) = 4; max_so_far = 4 - -1: max_ending_here = max(4-1,-1) = 3; max_so_far = 4 - -2: max_ending_here = max(3-2,-2) = 1; max_so_far = 4 - 1: max_ending_here = max(1+1,1) = 2; max_so_far = 4 - 5: max_ending_here = max(2+5,5) = 7; max_so_far = 7 - -3: max_ending_here = max(7-3,-3) = 4; max_so_far = 7Step 2: Identify subarray producing max sum
The max sum is 7, produced by subarray [4, -1, -2, 1, 5].Final Answer:
7, subarray [4, -1, -2, 1, 5] -> Option BQuick Check:
Max sum 7 from subarray [4, -1, -2, 1, 5] [OK]
- Including -3 in max subarray incorrectly
- Choosing shorter subarray with smaller sum
- Miscomputing max_ending_here updates
Ready to prove it?
Pass the test and this pattern moves unknown
