12Kadane's algorithmArrays and hashing

Kadane's algorithm

The largest sum of numbers in a row: drop the running sum as soon as it goes below zero.

Problem: LeetCode 53 · Maximum Subarray (Medium). Given an integer array nums, return the largest sum of a non-empty subarray (numbers in a row).

Worked example: nums = [-2, 3, -1, 4, -7, 5] → 6 (the subarray 3 - 1 + 4).

index012345
nums-23-14-75
current (after adding the number)-23 (fresh)26-15 (fresh)
best (largest so far)-233666

Quick check from the post: change -7 to -2 and the best becomes 9 (3 - 1 + 4 - 2 + 5).

The idea

Walk through the numbers keeping a sum, current. Before adding the next number, check it: if current is below 0 it can only drag the next number down, so drop it and start fresh from 0. Keep the largest value current reaches in best. best starts at nums[0] (see the trap below). current can start at 0, because the first number is always added to it.

This is the same as the common one-line form current = max(x, current + x): adding to a negative current always gives less than x alone.

Pseudocode

Pseudocode · any language
function maxSubArray(nums):
    current = 0          // sum so far
    best = nums[0]       // largest so far
    for each x in nums:
        if current < 0:  // in debt?
            current = 0  // start fresh
        current = current + x
        best = max(best, current)
    return best

The trap: best starts at 0. A subarray needs at least one number. With nums = [-3, -1, -2], starting best at 0 returns 0, which is wrong; starting it at nums[0] finds [-1], so the answer is -1.

Code

public class Kadane {
    static int maxSubArray(int[] nums) {
        int current = 0;          // sum so far
        int best = nums[0];       // largest so far
        for (int x : nums) {
            if (current < 0) {    // in debt?
                current = 0;      // start fresh
            }
            current = current + x;
            best = Math.max(best, current);
        }
        return best;
    }
}

Complexity

  • Time: O(n), one pass over the array.
  • Extra space: O(1), just current and best.
  • Brute force (every subarray with a running sum) is O(n²) time.

How it was tested

All four programs were compiled and tested on 3,016 inputs: 3,000 random arrays (length 1 to 12, values in ±3, ±10 or ±10,000) plus edge cases (single element, all negative, all equal, sorted, reversed, the LeetCode examples, and 1,000-element arrays at the ±10,000 value limit). Every output matched an O(n²) brute force. With LeetCode's limits (n ≤ 10⁵, |nums[i]| ≤ 10⁴) the sum stays within ±10⁹, so a 32-bit int is safe in Java and C++, and JavaScript numbers are exact. Re-run on 31 October 2026 on 3,005 inputs (3,000 random arrays, the example, the quick check, the trap input, a single element and a 1,000-element array at the value limit): all four matched the brute force on every one.

Practice

Try these in order. Open the worked example first if you got stuck on the slides.