Kadane's Algorithm Maximum Subarray in DSA Typescript - Time & Space Complexity
We want to understand how the time needed to find the maximum sum of a continuous subarray changes as the input array grows.
How does the number of steps grow when the array gets bigger?
Analyze the time complexity of the following code snippet.
function maxSubArray(nums: number[]): number {
let maxSoFar = nums[0];
let maxEndingHere = nums[0];
for (let i = 1; i < nums.length; i++) {
maxEndingHere = Math.max(nums[i], maxEndingHere + nums[i]);
maxSoFar = Math.max(maxSoFar, maxEndingHere);
}
return maxSoFar;
}
This code finds the largest sum of any continuous part of the array using Kadane's algorithm.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: One loop that goes through each number in the array once.
- How many times: Exactly once for each element, so as many times as the array length.
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: Doubling the input size roughly doubles the work done.
Time Complexity: O(n)
This means the time to find the maximum subarray sum grows in a straight line with the size of the input array.
[X] Wrong: "Kadane's algorithm checks all possible subarrays, so it must be slower than O(n)."
[OK] Correct: Kadane's algorithm cleverly keeps track of sums as it goes, so it only needs one pass through the array, not checking every subarray separately.
Understanding this algorithm's time complexity shows you can spot efficient solutions that avoid unnecessary work, a key skill in problem solving.
"What if we changed the algorithm to check every possible subarray sum by nested loops? 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 any contiguous subarray within a given array.Step 2: Differentiate from other array operations
It does not find minimum elements, total sum, or count positives, but specifically the largest sum of a continuous segment.Final Answer:
The maximum sum of a contiguous subarray -> Option DQuick Check:
Maximum subarray sum = The maximum sum of a contiguous subarray [OK]
- Confusing max sum with total sum of array
- Thinking it finds minimum values
- Assuming it counts positive numbers
Solution
Step 1: Understand initialization for Kadane's Algorithm
We initialize maxSoFar to the smallest safe integer to handle arrays with negative numbers correctly, and maxEndingHere to 0.Step 2: Check each option's correctness
let maxSoFar = Number.MIN_SAFE_INTEGER, maxEndingHere = 0; correctly uses Number.MIN_SAFE_INTEGER for maxSoFar and 0 for maxEndingHere. Other options use incorrect types or values.Final Answer:
let maxSoFar = Number.MIN_SAFE_INTEGER, maxEndingHere = 0; -> Option AQuick Check:
Initialization with min safe integer = let maxSoFar = Number.MIN_SAFE_INTEGER, maxEndingHere = 0; [OK]
- Initializing maxSoFar to 0 causes wrong results with all negatives
- Using arrays instead of numbers for maxSoFar
- Setting variables to null instead of numbers
function maxSubArray(nums: number[]): number {
let maxSoFar = Number.MIN_SAFE_INTEGER;
let maxEndingHere = 0;
for (const num of nums) {
maxEndingHere = Math.max(num, maxEndingHere + num);
maxSoFar = Math.max(maxSoFar, maxEndingHere);
}
return maxSoFar;
}
console.log(maxSubArray([-2,1,-3,4,-1,2,1,-5,4]));Solution
Step 1: Trace the Kadane's Algorithm on the input array
Iterate through [-2,1,-3,4,-1,2,1,-5,4]: max subarray sums update as -2,1, -2,4,3,5,6,1,5.Step 2: Identify the maximum sum found
The maximum sum found during iteration is 6, which corresponds to subarray [4,-1,2,1].Final Answer:
6 -> Option AQuick Check:
Max subarray sum = 6 [OK]
- Adding all positive numbers only
- Ignoring negative numbers impact
- Confusing maxSoFar with maxEndingHere
function maxSubArray(nums: number[]): number {
let maxSoFar = 0;
let maxEndingHere = 0;
for (const num of nums) {
maxEndingHere = Math.max(num, maxEndingHere + num);
maxSoFar = Math.max(maxSoFar, maxEndingHere);
}
return maxSoFar;
}Solution
Step 1: Analyze initialization problem
Initializing maxSoFar to 0 causes wrong results if all numbers are negative, as maxSoFar never updates below 0.Step 2: Fix initialization to handle negative arrays
Setting maxSoFar to Number.MIN_SAFE_INTEGER allows correct tracking of max sums even if all are negative.Final Answer:
Initialize maxSoFar with Number.MIN_SAFE_INTEGER instead of 0 -> Option BQuick Check:
Proper initialization fixes negative-only arrays [OK]
- Leaving maxSoFar as 0 causes wrong max for negatives
- Removing reset of maxEndingHere breaks algorithm logic
- Returning wrong variable from function
Choose the correct approach.
Solution
Step 1: Understand Kadane's Algorithm extension for indices
When maxEndingHere resets to current element, update start index; when maxSoFar updates, update end index to current position.Step 2: Compare with other approaches
Storing all subarrays or using nested loops is inefficient; returning first positive index is incorrect.Final Answer:
Track start index when maxEndingHere resets; update end index when maxSoFar updates -> Option CQuick Check:
Index tracking with resets and updates = Track start index when maxEndingHere resets; update end index when maxSoFar updates [OK]
- Using nested loops loses Kadane's efficiency
- Ignoring index updates when maxEndingHere resets
- Assuming first positive element is max subarray start
Ready to prove it?
Pass the test and this pattern moves unknown
