Maximum Sum Subarray II in O(n) Time Complexity using Java

( Kadane's Algorithm )


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) time and use O(1) extra space.


Understanding the Problem

The core challenge of this problem is to find the maximum sum of a contiguous subarray within a one-dimensional numeric array. This problem is significant in various fields such as finance (for finding maximum profit), computer science (for optimization problems), and more. A common pitfall is to consider non-contiguous subarrays or to use a brute-force approach that is not efficient.

Approach

To solve this problem, we can use Kadane's Algorithm, which is an efficient way to find the maximum sum subarray in linear time.

Naive Solution

A naive solution would involve checking all possible subarrays and calculating their sums, which would result in a time complexity of O(n^2). This is not optimal for large arrays.

Optimized Solution: Kadane's Algorithm

Kadane's Algorithm improves upon the naive solution by maintaining a running sum of the maximum subarray ending at the current position. It uses two variables: maxCurrent and maxGlobal. The algorithm iterates through the array, updating these variables based on the current element and the running sum.

Algorithm

  1. Initialize maxCurrent and maxGlobal to the first element of the array.
  2. Iterate through the array starting from the second element.
  3. For each element, update maxCurrent to be the maximum of the current element and the sum of maxCurrent and the current element.
  4. If maxCurrent is greater than maxGlobal, update maxGlobal.
  5. Return maxGlobal as the result.

Code Implementation

public class MaximumSumSubarray {
    public static int maxSubArray(int[] nums) {
        // Initialize maxCurrent and maxGlobal with the first element of the array
        int maxCurrent = nums[0];
        int maxGlobal = nums[0];

        // Iterate through the array starting from the second element
        for (int i = 1; i < nums.length; i++) {
            // Update maxCurrent to be the maximum of the current element and the sum of maxCurrent and the current element
            maxCurrent = Math.max(nums[i], maxCurrent + nums[i]);

            // Update maxGlobal if maxCurrent is greater
            if (maxCurrent > maxGlobal) {
                maxGlobal = maxCurrent;
            }
        }

        // Return the maximum sum of the subarray
        return maxGlobal;
    }

    public static void main(String[] args) {
        int[] nums = {-2, -5, 6, -2, -3, 1, 5, -6};
        System.out.println("Maximum Sum Subarray: " + maxSubArray(nums)); // Output: 7
    }
}

Complexity Analysis

The time complexity of Kadane's Algorithm is O(n) because it involves a single pass through the array. The space complexity is O(1) as it uses a constant amount of extra space.

Edge Cases

Potential edge cases include:

  • 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.

Examples:

Input: [-1, -2, -3]
Output: -1

Input: [1]
Output: 1

Input: [1, 2, 3, -2, 5]
Output: 9

Testing

To test the solution comprehensively, consider a variety of test cases:

  • Simple cases with small arrays.
  • Arrays with all negative numbers.
  • Arrays with a mix of positive and negative numbers.
  • Large arrays to test performance.

Using a testing framework like JUnit can help automate and manage these tests effectively.

Thinking and Problem-Solving Tips

When approaching such problems:

  • Understand the problem requirements and constraints thoroughly.
  • Start with a brute-force solution to understand the basic approach.
  • Look for patterns and optimizations to improve efficiency.
  • Practice similar problems to build intuition and problem-solving skills.

Conclusion

Understanding and implementing Kadane's Algorithm is crucial for solving maximum sum subarray problems efficiently. This problem is a great example of how dynamic programming can optimize solutions. Practice and familiarity with such algorithms will enhance your problem-solving skills.

Additional Resources

For further reading and practice: