Start learning free

LESSON 226 OF 409 · FREE CODING INTERVIEW QUESTIONS

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

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

    C++ · FREE CODING INTERVIEW QUESTIONS

    Maximum Sum Subarray in C++, explained

    Understanding the Problem

    The core challenge of this problem is to find the subarray with the maximum sum in an array that contains both positive and negative integers. This problem is significant in various fields such as finance (to find the best time to buy and sell stocks) and computer science (for optimization problems).

    Potential pitfalls include misunderstanding the definition of a subarray (which must be contiguous) and not considering negative numbers correctly.

    Approach

    To solve this problem, we can start with a naive approach and then optimize it:

    Naive Approach

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

    maxSum = nums[0]
    for each i : 0 -> n - 1:
        for each j : i -> n - 1:
            maxSum = max(maxSum, sum(nums[i...j]))
    return maxSum
    

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

    Optimized Approach

    We can optimize the naive approach by calculating the sum of subarrays in O(1) time using a running sum:

    maxSum = nums[0]
    for each i : 0 -> n - 1:
        sum = 0
        for each j : i -> n - 1:
            sum += nums[j]
            maxSum = max(maxSum, sum)
    return maxSum
    

    This approach reduces the time complexity to O(n^2) while maintaining O(1) space complexity.

    Algorithm

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

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

    Code Implementation

    #include <iostream>
    #include <vector>
    #include <algorithm> // for std::max
    
    int maxSubArraySum(const std::vector<int>& nums) {
        int maxSum = nums[0]; // Initialize maxSum to the first element
        int n = nums.size();
        
        for (int i = 0; i < n; ++i) {
            int sum = 0; // Initialize sum for the current subarray
            for (int j = i; j < n; ++j) {
                sum += nums[j]; // Add the current element to the sum
                maxSum = std::max(maxSum, sum); // Update maxSum if needed
            }
        }
        
        return maxSum; // Return the maximum subarray sum
    }
    
    int main() {
        std::vector<int> nums = {-2, -5, 6, -2, -3, 1, 5, -6};
        std::cout << "Maximum Sum Subarray: " << maxSubArraySum(nums) << std::endl;
        return 0;
    }
    

    Complexity Analysis

    The time complexity of the optimized approach is O(n^2) due to the 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 least negative number.
    • 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:

    Test Case 1:
    Input: [1, 2, 3, 4, 5]
    Expected Output: 15
    
    Test Case 2:
    Input: [-1, -2, -3, -4, -5]
    Expected Output: -1
    
    Test Case 3:
    Input: [3, -2, 5, -1]
    Expected Output: 6
    
    Test Case 4:
    Input: [1]
    Expected Output: 1
    

    Thinking and Problem-Solving Tips

    When approaching such problems, consider the following tips:

    • Understand the problem requirements and constraints thoroughly.
    • Start with a brute force approach to get a basic solution.
    • Look for patterns and ways to optimize the solution.
    • Practice similar problems to improve problem-solving skills.

    Conclusion

    In this blog post, we discussed the problem of finding the maximum sum subarray in an array containing both positive and negative integers. We explored a naive approach and an optimized approach, provided a detailed algorithm, and implemented the solution in C++. Understanding and solving such problems is crucial for improving problem-solving skills and preparing for coding interviews.

    Additional Resources

    For further reading and practice, consider the following resources:


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