DSA Trainer
← All patterns
Pattern

Kadane's Algorithm Pattern

Extend the streak if it helps. Drop it if it hurts. Track the best you've seen.

Quick Summary

Best used when

  • You need the maximum (or minimum) sum of a contiguous subarray
  • At each element, you decide whether to extend the current streak or restart from here
  • The brute force checks all subarrays by computing each sum from scratch
  • Carrying a negative running sum always makes the answer worse

Clue words in the problem

maximum subarraycontiguoussubarray sumlargest sumnon-empty

Complexity gain

O(n²) all-subarray enumeration → O(n) single pass

Why this pattern matters for LeetCode

The brute force checks every possible subarray by computing its sum from scratch each time. That is O(n²). Kadane's is O(n) because it makes one local decision at each element: extend or restart. If the running sum is positive, extending can only help. If it's negative, you're better off starting fresh from the current element. You never need to look backward — just the running sum and the current element.

What the Kadane's Algorithm pattern is

Kadane's Algorithm maintains two values as it scans: currentSum (the best sum of any subarray ending at the current position) and maxSum (the best seen anywhere so far). At each element, currentSum = max(nums[i], currentSum + nums[i]). This is the 'extend or restart' decision: take just this element alone, or add it to the running total. Update maxSum whenever currentSum improves it.

Reach for Kadane's Algorithm when you catch yourself thinking…

These are the internal questions that signal this pattern.

Am I finding the maximum (or minimum) sum of a contiguous subarray?
At each step, do I need to decide whether to restart or extend the current subarray?
Does the brute force check every subarray by summing it from scratch?
Does carrying a negative running sum always make the answer worse?

Beginner mental model

You're on a road trip tracking your cumulative gas costs. At each gas station, you decide: keep going (add this cost to my running total), or declare this the new start (reset and begin fresh from here). You keep a mental note of the best outcome you've hit. Kadane's does the same with sums — at each element, you pick whichever is bigger: start fresh here, or extend what you had. Track the best currentSum you've ever seen as the answer.

Ready to practice Kadane's Algorithm?

DSA Trainer gives you guided hints, not answers, so you build real intuition.

When to use Kadane's Algorithm

  • Maximum subarray sum (the classic Kadane's problem)
  • Minimum subarray sum (negate all values and find the max)
  • Maximum product subarray (modified Kadane's tracking both max and min)
  • Any problem where the optimal contiguous subarray is determined greedily element by element

When NOT to use Kadane's Algorithm

  • The subarray doesn't need to be contiguous — use a different approach
  • You need to return the actual subarray, not just the sum — you can extend Kadane's to track start/end, but it's more complex
  • The constraint involves a fixed window size — use Sliding Window instead
  • You need the sum of k largest elements — use a heap or sort

Better alternative: In those cases, Sliding Window (for fixed-size windows) or a prefix sum approach may be more appropriate.

JavaScript code template

Maximum Subarray — O(n) time, O(1) space

function maxSubArray(nums) {
  // Initialize to nums[0], NOT 0 — handles all-negative arrays correctly
  let maxSum = nums[0];
  let currentSum = nums[0];

  for (let i = 1; i < nums.length; i++) {
    // Extend the current subarray, or restart from nums[i] alone?
    currentSum = Math.max(nums[i], currentSum + nums[i]);

    // Did we just find a new best?
    maxSum = Math.max(maxSum, currentSum);
  }

  return maxSum;
}

Both values start at nums[0] to handle all-negative arrays correctly. Starting at index 1, the extend-or-restart decision runs at each element: if currentSum + nums[i] > nums[i], the existing streak is helping — extend it. Otherwise, it's a drag — restart from nums[i] alone. maxSum captures the best currentSum seen across the entire scan.

Step-by-step thinking process

Walk through this in your head before writing code.

  1. 1Initialize maxSum = nums[0] and currentSum = nums[0] — NOT zero.
  2. 2Start the loop at index 1 (not 0, since nums[0] is already accounted for).
  3. 3At each element: currentSum = Math.max(nums[i], currentSum + nums[i]).
  4. 4This is the extend-or-restart decision — whichever is larger wins.
  5. 5Update maxSum = Math.max(maxSum, currentSum) to track the global best.
  6. 6Return maxSum after the loop.

LeetCode-style problems that use this pattern

Practice on DSA Trainer with guided hints: no spoilers, just nudges.

Coming soon

  • Maximum Sum Circular Subarray

    Max of: standard Kadane's on the array, or total sum minus minimum subarray sum.

    Coming soon

Common mistakes beginners make

  • Initializing maxSum or currentSum to 0 — this fails when all elements are negative. The answer should be the least negative number, not 0.
  • Starting the loop at index 0 after initializing both values from nums[0] — you'll double-count the first element.
  • Forgetting to update maxSum inside the loop — if you only update at the end, you'll miss the true maximum.
  • Confusing currentSum (best subarray ending here) with maxSum (best subarray seen anywhere) — you need both and they serve different roles.

Kadane's vs Sliding Window vs Dynamic Programming

Choose the right tool for the job.

PatternUse when…
Kadane's AlgorithmFinding maximum/minimum contiguous subarray sum — greedy local decision at each element
Sliding WindowTracking a contiguous range with an explicit constraint (window size, character count) that determines when to expand or shrink
Dynamic ProgrammingThe subproblem structure is more complex — Kadane's is actually a space-optimized DP where you only need the previous state

Time and space complexity

Time complexity

O(n)

Space complexity

O(1)

One pass through the array — each element is visited exactly once. The two variables (currentSum, maxSum) take O(1) space. No recursion, no extra arrays. This is as lean as it gets for a subarray problem.

Ready to practice Kadane's Algorithm?

DSA Trainer gives you guided hints, not answers, so you build real intuition.

Frequently asked questions

Why do we initialize to nums[0] instead of 0?
If you initialize maxSum to 0 and all numbers are negative, you'll return 0 — but 0 isn't a valid subarray answer (the problem requires at least one element). Initializing to nums[0] ensures you always return the least negative element in an all-negative array.
What does 'extend or restart' actually mean?
At each element nums[i], you choose between: starting a brand new subarray at nums[i] (restart), or adding nums[i] to whatever subarray ended at i-1 (extend). You pick whichever gives a larger currentSum. If currentSum was negative, extending always makes things worse — so you restart.
Is Kadane's Algorithm a form of dynamic programming?
Yes, technically. The recurrence is: dp[i] = max(nums[i], dp[i-1] + nums[i]), where dp[i] is the maximum subarray sum ending at index i. Kadane's is the space-optimized version — instead of keeping the entire dp array, you only keep the previous value (currentSum). The answer is max of all dp[i] values (maxSum).
What happens with all-negative input like [-3, -1, -2]?
Kadane's handles it correctly when initialized to nums[0]. Both maxSum and currentSum start at -3. At index 1: currentSum = max(-1, -3 + (-1)) = max(-1, -4) = -1. maxSum = max(-3, -1) = -1. At index 2: currentSum = max(-2, -1 + (-2)) = max(-2, -3) = -2. maxSum stays -1. Correct answer: -1.
How is Kadane's different from a sliding window?
Kadane's doesn't maintain an explicit window — it 'resets' the window whenever starting fresh is better. A sliding window maintains a well-defined range [left, right] and adjusts it based on a constraint. Kadane's constraint ('is the running sum positive?') collapses the window tracking into a single variable.

Explore other patterns