53. Maximum Subarray
On LeetCode ->Reformulated question¶
Given a non-empty integer array nums, return the largest possible sum of any contiguous subarray.
Example:
Key trick¶
Use Kadane's algorithm:
- Keep the best sum ending at the current index.
- Either extend the previous subarray or start fresh at the current number.
- Track the global maximum.
Trap¶
Common mistakes:
- Returning
0for all-negative arrays. - Resetting too early and losing the case where the best subarray is a single negative number.
- Confusing contiguous subarray with subsequence.
Why this question is interesting¶
It is a simple-looking problem that tests whether you can:
- Turn a brute force idea into a linear-time DP/greedy solution.
- Maintain the right invariant with only \(O(1)\) extra space.
Solve the problem with idiomatic python¶
class Solution:
def maxSubArray(self, nums: list[int]) -> int:
# best sum of a subarray ending at current position
cur = nums[0]
# best sum seen anywhere
best = nums[0]
for x in nums[1:]:
# either extend previous subarray or start at x
cur = max(x, cur + x)
best = max(best, cur)
return best
Pytest test¶
import pytest
@pytest.mark.parametrize(
("nums", "expected"),
[
([-2, 1, -3, 4, -1, 2, 1, -5, 4], 6),
([1], 1),
([5, 4, -1, 7, 8], 23),
([-1], -1),
([-5, -2, -7], -2),
([0, 0, 0], 0),
([8, -19, 5, -4, 20], 21),
([1, -1, 1, -1, 1], 1),
],
)
def test_max_sub_array(nums, expected):
assert Solution().maxSubArray(nums) == expected
Comment my solution¶
Your solution is correct and linear.
Small improvements:
- Use the standard Kadane form
cur = max(x, cur + x). - It is simpler than storing
cur_sumasmax(sum, 0). - Your comments are a bit long for an interview; shorter invariants are easier to explain.
import pytest
class Solution:
def maxSubArray(self, nums: list[int]) -> int:
best_sum = nums[0] # up to i - 1 (here i = 1)
# subarray up to i - 1 with largest sum
# we restart the array when adding it nums[i] go
cur_sum = max(nums[0], 0)
for n in nums[1:]:
new_sum = cur_sum + n
if best_sum < new_sum:
best_sum = new_sum
# if new_sum < 0, we want to start a new subarray on the next
# number in nums. So we reset cur_sum to 0.
# if not, we continue summing on the current subarray
cur_sum = max(new_sum, 0)
return best_sum
@pytest.mark.parametrize(
("nums", "expected_max"),
[
([-2,1,-3,4,-1,2,1,-5,4], 6), # [4,-1,2,1]
([1], 1),
([5,4,-1,7,8], 23) # [5,4,-1,7,8]
]
)
def test_maxSubArray(nums, expected_max):
assert Solution().maxSubArray(nums) == expected_max
A cleaner version of your idea: