Start learning free

LESSON 227 OF 410 · FREE CODING INTERVIEW QUESTIONS

Maximum Sum Subarray in O(n^2) Time Complexity using Python

Practice O(n2) Read the full explanation

Given an input array that may contain both positive and negative integers, find the sum of continuous subarray of numbers which has the largest sum.

Example:

Input: nums = [-2, -5, 6, -2, -3, 1, 5, -6]
Output: 7
Explanation: sum([6, -2, -3, 1, 5]) = 7

Note:

Your algorithm should run in O(n^2) time and use O(1) extra space.




Let's come up with a brute force approach. Brute force tries each and every candidate to our solution. For this problem, the candidates are all the subarrays of nums. How can we try out each subarray?

A subarray is defined by its left endpoint, let's name it index i and its right point, let's name it index j. We should go through each pair of indices (i, j) such that 0 <= i <= j < n, where n is the length of nums. How can we achieve this?

Using two nested for loops! The first loop will try out each possible i between 0 and n - 1. The second loop will be written inside the first one and will try out each possible j between i and n - 1.
for each i : 0 to n - 1:
		for each j : i to n - 1:
	
We will use a variable maxSum to store the greatest sum found so far and for each pair (i, j), update maxSum with sum(nums[i...j]) if it's the case:
maxSum = nums[0]
for each i : 0 to n - 1:
	for each j : i to n - 1:
		maxSum = max(maxSum, sum(nums[i...j]))
return maxSum
All we have to do now is find a way of getting sum(nums[i...j]) in O(1) time. How can we do this?

One way is using Partial Sums. But that implies using an extra array, which takes O(n) extra space. There is a better way. We can use a variable sum to store the sum of the current subarray sum(nums[i...j]).
maxSum = nums[0]
for each i : 0 to n - 1:
	for each j : i to n - 1:
		maxSum = max(maxSum, sum)
return maxSum
How should we update this variable throught the algorithm to make sure that it always stores the correct sum?

Each time we increment j in the second loop, we should add nums[j] to sum. Also, each time we increment i in the first loop, we start with a new empty subarray so we should reset sum to 0:
maxSum = nums[0]
for each i : 0 to n - 1:
	sum = 0
	for each j : i to n - 1:
		sum += nums[j]
		maxSum = max(maxSum, sum)
return maxSum

STEP 1 OF 7
    Ctrl + Enter to check

    PYTHON · FREE CODING INTERVIEW QUESTIONS

    Maximum Sum Subarray in Python, explained

    Problem Definition

    The problem requires finding the maximum sum of a continuous subarray within a given array of integers, which may include both positive and negative numbers.

    Input:

    • An array of integers, nums.

    Output:

    • An integer representing the maximum sum of a continuous subarray.

    Constraints:

    • The algorithm should run in O(n^2) time complexity.
    • The algorithm should use O(1) extra space.

    Example:

    Input: nums = [-2, -5, 6, -2, -3, 1, 5, -6]
    Output: 7
    Explanation: sum([6, -2, -3, 1, 5]) = 7

    Understanding the Problem

    The core challenge is to identify the subarray with the maximum sum. This problem is significant in various applications such as financial analysis, where one might want to find the period with the maximum profit.

    Potential pitfalls include misunderstanding the requirement for a continuous subarray and not considering negative numbers correctly.

    Approach

    To solve this problem, we can start with a brute force approach and then optimize it.

    Naive Solution

    The naive solution involves checking all possible subarrays and calculating their sums. This can be achieved using two nested loops:

    maxSum = nums[0]
    for i in range(len(nums)):
        for j in range(i, len(nums)):
            currentSum = sum(nums[i:j+1])
            maxSum = max(maxSum, currentSum)
    return maxSum
    

    While this approach is straightforward, it is not optimal as it has a time complexity of O(n^3) due to the sum calculation inside the inner loop.

    Optimized Solution

    We can optimize the naive solution by maintaining a running sum of the current subarray. This reduces the time complexity to O(n^2):

    maxSum = nums[0]
    for i in range(len(nums)):
        currentSum = 0
        for j in range(i, len(nums)):
            currentSum += nums[j]
            maxSum = max(maxSum, currentSum)
    return maxSum
    

    This approach ensures that we only traverse the array twice, making it more efficient.

    Algorithm

    Here is a step-by-step breakdown of the optimized algorithm:

    1. Initialize maxSum with the first element of the array.
    2. Use a nested loop to iterate over all possible subarrays.
    3. Maintain a running sum of the current subarray.
    4. Update maxSum if the current subarray sum is greater.
    5. Return maxSum after all iterations.

    Code Implementation

    def max_subarray_sum(nums):
        # Initialize maxSum with the first element of the array
        maxSum = nums[0]
        
        # Iterate over all possible subarrays
        for i in range(len(nums)):
            currentSum = 0
            for j in range(i, len(nums)):
                # Add the current element to the running sum
                currentSum += nums[j]
                # Update maxSum if the current sum is greater
                maxSum = max(maxSum, currentSum)
        
        return maxSum
    
    # Example usage
    nums = [-2, -5, 6, -2, -3, 1, 5, -6]
    print(max_subarray_sum(nums))  # Output: 7
    

    Complexity Analysis

    The time complexity of the optimized solution is O(n^2) because of the two nested loops. The space complexity is O(1) as we are using only a few extra variables.

    Edge Cases

    Consider the following edge cases:

    • All negative numbers: The algorithm should return the maximum single element.
    • Single element array: The algorithm should return that element.
    • Mixed positive and negative numbers: The algorithm should correctly identify the subarray with the maximum sum.

    Testing

    To test the solution comprehensively, consider the following test cases:

    def test_max_subarray_sum():
        assert max_subarray_sum([-2, -5, 6, -2, -3, 1, 5, -6]) == 7
        assert max_subarray_sum([-1, -2, -3, -4]) == -1
        assert max_subarray_sum([1, 2, 3, 4]) == 10
        assert max_subarray_sum([1]) == 1
        assert max_subarray_sum([-1, 2, 3, -4, 5, -6]) == 6
    
    test_max_subarray_sum()
    

    Thinking and Problem-Solving Tips

    When approaching such problems, consider the following tips:

    • Break down the problem into smaller parts.
    • Start with a brute force solution and then optimize.
    • Understand the constraints and edge cases.
    • Practice similar problems to improve problem-solving skills.

    Conclusion

    Understanding and solving the maximum sum subarray problem is crucial for developing strong problem-solving skills. Practice and exploration of different approaches can help in mastering such problems.

    Additional Resources

    For further reading and practice, consider the following resources:


    Keep going with PythonAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free