↓Skip to main content
  1. Algorithms/

Kadane's Algorithm

·2 mins· ·
Algorithm Kadane Dynamic-Programming Array
Wei Yi Chung
Author
Wei Yi Chung
Working at the contributing of open source, distributed systems, and data engineering.
Table of Contents

Introduction
#

Kadane’s Algorithm solves the maximum subarray problem in linear time. The important idea is not just “keep a running sum”; it is to define a precise DP state:

curr = maximum subarray sum ending at the current index
best = maximum subarray sum seen anywhere so far

This ending-here invariant is what makes the algorithm safe on arrays with negative numbers.

Core Idea
#

At each value x, the best subarray ending here has only two choices:

  • start a new subarray at x
  • extend the previous best subarray ending at the previous index

So the recurrence is:

curr = max(x, curr + x)
best = max(best, curr)

Initialize both values from nums[0], not from 0, because the answer may be negative.

Template
#

from typing import List

def max_subarray(nums: List[int]) -> int:
    curr = best = nums[0]

    for x in nums[1:]:
        curr = max(x, curr + x)
        best = max(best, curr)

    return best

Explanation of the Key Parameters
#

  • curr: best sum of a subarray that must end at the current element.
  • best: best sum found globally.
  • max(x, curr + x): choose between restarting and extending.

Common Mistakes
#

  • Initializing curr or best to 0, which breaks all-negative arrays.
  • Returning curr instead of best.
  • Describing curr vaguely as “current sum” instead of the maximum sum ending here.

Examples
#

For:

nums = [-2,1,-3,4,-1,2,1,-5,4]

The best subarray is:

[4, -1, 2, 1]

with sum:

6

Related LeetCode#

  • LC 53 Maximum Subarray
  • LC 152 Maximum Product Subarray, which needs both max-ending-here and min-ending-here because negative values can flip the sign.
  • LC 3984 Divisible Game: for each candidate prime k, count divisible values as positive and the rest as negative, and run Kadane once.
  • LC 1186 Maximum Subarray Sum with One Deletion: one more state for “one element already deleted”, with the answer updated at every step.

Related

LeetCode 313: Super Ugly Number
·2 mins
LeetCode Medium Array Math Dynamic-Programming
LeetCode 313 note: generalizing LC 264 with one pointer per prime; with a heap, avoid pushing the same number many times
LeetCode 396: Rotate Function
·2 mins
LeetCode Medium Array Math Dynamic-Programming
LeetCode 396 note: F(k) and F(k - 1) differ by one formula: F(k) = F(k - 1) + sum - n × the element moved to the front
LeetCode 435: Non-overlapping Intervals
·3 mins
LeetCode Medium Array Dynamic-Programming Greedy Sorting
LeetCode 435 note: minimum removals = total minus the maximum kept; sort by right end and greedily keep the one ending earliest
LeetCode 473: Matchsticks to Square
·2 mins
LeetCode Medium Array Dynamic-Programming Backtracking Bit-Manipulation
LeetCode 473 note: the total must be divisible by 4; place sticks from longest to shortest into one of four sides, skipping a side that would overflow or that equals a side already tried
LeetCode 42: Trapping Rain Water
·2 mins
LeetCode Hard Array Two-Pointers Dynamic-Programming Stack
LeetCode 42 note: each cell holds min(tallest on the left, tallest on the right) - its own height; use prefix and suffix maxima or two pointers
LeetCode 118: Pascal's Triangle
·1 min
LeetCode Easy Array Dynamic-Programming
LeetCode 118 note: each row starts and ends with 1, and every inner cell is the sum of the two cells above it