Tags: "leetcode", "dynamic-programming", "kadanes-algorithm", "prefix-sum", access_time 2-min read

Edit this post on Github

Maximum Subarray

Created: February 20, 2019 by [lek-tin]

Last updated: October 11, 2019

Given an integer array nums, find the contiguous subarray (containing at least one number) which has the largest sum and return its sum.

Example:

Input: [-2,1,-3,4,-1,2,1,-5,4],
Output: 6
Explanation: [4,-1,2,1] has the largest sum = 6.

Follow up:

If you have figured out the O(n) solution, try coding another solution using the divide and conquer approach, which is more subtle.

Solution (Dynamic Programming)

class Solution {
    public int maxSubArray(int[] nums) {
        if (nums.length == 0) {
            return 0;
        }

        int[] mem = new int[nums.length];
        mem[0] = nums[0];
        int max = nums[0];
        for (int i = 1; i < nums.length; i++) {
            mem[i] = mem[i-1] > 0 ? mem[i-1] + nums[i] : nums[i];
            max = Math.max(mem[i], max);
        }

        return max;
    }
}

Solution (prefix sum)

class Solution:
    def maxSubArray(self, nums: List[int]) -> int:
        prefixSum, minSum, maxSum = 0, 0, -math.inf

        for i, num in enumerate(nums):
            # prefixSum[n+1] = prefixSum[n] + nums[n+1]
            prefixSum += num
            # maxSum = prefixSum[n+1] - min{prefixSum[0-->n]}
            maxSum = max(prefixSum-minSum, maxSum)
            # Update minSum now we have min{prefixSum[0-->n+1]}
            # we only care when minSum is negative because so want to drop any negative preSum
            minSum = min(prefixSum, minSum)

        return maxSum

Prefix Sum Maximum Subarray

Need to return the max subarray

import math

class Solution:
    def maxSubArray(self, nums: List[int]) -> int:
        preSums, minSum, maxSum = 0, 0, -math.inf

        start, left, right = 0, 0, 0

        for i, num in enumerate(nums):
            preSums += num
            if maxSum < preSums:
                maxSum = preSums
                left = start
                right = i
            if preSums < 0:
                preSums = 0
                start = i+1

        return nums[left:right+1]

Solution (Kadane’s Algorithm)

kadane’s algorithm example

class Solution:
    def maxSubArray(self, nums: List[int]) -> int:
        n = len(nums)
        if n == 0:
            return 0

        localMaxSum = globalMaxSum = nums[0]

        for i in range(1, n):
            # restart if previous local max sum is negative
            localMaxSum = max(localMaxSum+nums[i], nums[i])
            globalMaxSum = max(globalMaxSum, localMaxSum)

        return globalMaxSum