LeetCode Ā· #53

Maximum Subarray Solution

Given an integer array, find the subarray with the largest sum and return its sum.

01
Section One Ā· Problem

Problem Statement

šŸ·ļø

Difficulty

Medium

šŸ”—

LeetCode

Problem #53

šŸ—ļø

Pattern

Greedy / DP — Kadane's algorithm

Given integer array nums, find the contiguous subarray (containing at least one element) with the largest sum and return its sum.

Example
Input: nums = [-2,1,-3,4,-1,2,1,-5,4] Output: 6 // Subarray [4,-1,2,1] has the largest sum 6.
Constraints
• 1 ≤ nums.length ≤ 10⁵ • -10⁓ ≤ nums[i] ≤ 10⁓
02
Section Two Ā· Approach 1

Brute Force — O(n²)

Try every subarray start and end. Track running sum and global max.

Problem: O(n²) is too slow for n=10⁵. Kadane's insight: if the running sum drops below 0, reset — a negative prefix can only hurt future sums.
Java — O(n²)
class Solution { public int maxSubArray(int[] nums) { int best = Integer.MIN_VALUE; for (int i = 0; i < nums.length; i++) { int sum = 0; for (int j = i; j < nums.length; j++) { sum += nums[j]; best = Math.max(best, sum); } } return best; } }
Python — O(n²)
class Solution: def maxSubArray(self, nums: list[int]) -> int: best = float('-inf') for i in range(len(nums)): s = 0 for j in range(i, len(nums)): s += nums[j] best = max(best, s) return best
03
Section Three Ā· Approach 2

Kadane's Algorithm — O(n) time, O(1) space

Maintain a running sum cur. At each element: cur = max(nums[i], cur + nums[i]). If the previous sum is negative, start fresh. Track the global maximum.

šŸ’” Mental model: You're carrying a bucket collecting water (positive numbers) and leaking water (negative numbers). At each step, you either keep carrying the bucket or dump it and start with a fresh bucket. The answer is the most water you ever had in the bucket. Kadane's says: if the bucket is lighter than what you'd get starting fresh (i.e., running sum < current element alone), dump and restart.
Algorithm
  • cur = nums[0], best = nums[0].
  • For i from 1 to n-1: cur = max(nums[i], cur + nums[i]). best = max(best, cur).
  • Return best.
šŸŽÆ When to recognize this pattern: "Maximum sum contiguous subarray." THE classic greedy/DP problem. Kadane's is the answer. Variants: LC 152 (Maximum Product Subarray — track min and max), LC 918 (Max Circular Subarray — handle wrap-around).
04
Section Four Ā· Trace

Visual Walkthrough

Trace for nums = [-2, 1, -3, 4, -1, 2, 1, -5, 4].

Maximum Subarray — Kadane's
cur = max(nums[i], cur+nums[i]). best = max(best, cur). i: 0 1 2 3 4 5 6 7 8 num: -2 1 -3 4 -1 2 1 -5 4 cur: -2 1 -2 4 3 5 6 1 5 best: -2 1 1 4 4 5 6 6 6 i=1: cur=max(1, -2+1)=max(1,-1)=1. Reset! Start fresh at 1. i=3: cur=max(4, -2+4)=max(4,2)=4. Reset again! Start fresh at 4. i=6: cur=5+1=6. best=6. ← peak! Subarray [4,-1,2,1]. return 6 āœ“
05
Section Five Ā· Implementation

Code — Java & Python

Java — Kadane's
class Solution { public int maxSubArray(int[] nums) { int cur = nums[0], best = nums[0]; for (int i = 1; i < nums.length; i++) { cur = Math.max(nums[i], cur + nums[i]); // extend or restart best = Math.max(best, cur); } return best; } }
Python — Kadane's
class Solution: def maxSubArray(self, nums: list[int]) -> int: cur = best = nums[0] for n in nums[1:]: cur = max(n, cur + n) best = max(best, cur) return best
06
Section Six Ā· Analysis

Complexity Analysis

ApproachTimeSpaceTrade-off
Brute forceO(n²)O(1)All subarrays
Divide & conquerO(n log n)O(log n)Split + merge cross-sum
Kadane's ← optimalO(n)O(1)Single pass, two variables
07
Section Seven Ā· Edge Cases

Edge Cases & Pitfalls

CaseInputWhy It Matters
All negative[-3,-2,-1]Answer is -1 (least negative). Kadane handles: never resets to 0.
Single element[5]Answer is 5.
All positive[1,2,3]Entire array is the answer. sum=6.
Zero in middle[1,0,-1]Best is [1,0]=1 or [1]=1.
⚠ Common Mistake: Initializing cur = 0 and best = 0. If all elements are negative, this returns 0 — which isn't a valid subarray sum (the problem requires at least one element). Always initialize with nums[0].

← Back to Greedy problems