I would like to add an answer that contains 2 approaches that handle the array in different ways with or without positive elements, written in Java .
Code - Java
MaxSubSum.java:
public class MaxSubSum { /** * Find max sub array, only include sub array with positive sum. * <p>For array that only contains non-positive elements, will choose empty sub array start from 0. * <p>For empty input array, will choose empty sub array start from 0. * * @param arr input array, * @return array of length 3, with elements as: {maxSum, startIdx, len}; * <p>tips: should use 'len' when loop the returned max sub array, so that it could also work for empty sub array, */ public static int[] find(int[] arr) { if (arr.length == 0) return new int[]{0, 0, 0}; // empty array, no sub array, int maxSum = 0; // max sum, found so far, int maxStart = 0; // start of max sum, int maxLen = 0; // length of max subarray, int sum = 0; // current sum, int start = 0; // current start, for (int i = 0; i < arr.length; i++) { if (arr[i] > 0) { // get a positive, if (sum <= 0) { // should restart, start = i; sum = arr[i]; } else sum += arr[i]; if (sum > maxSum) { // get a larger sum, maxSum = sum; maxStart = start; maxLen = i - start + 1; } } else sum += arr[i]; // 0 or negative number, } return new int[]{maxSum, maxStart, maxLen}; } /** * Find max sub array, also include sub array with non-positive sum. * <p>For array that only contains non-positive elements, will choose first smallest element. * <p>For empty input array, will choose empty sub array start from 0. * * @param arr input array, * @return array of length 3, with elements as: {maxSum, startIdx, len}; * <p>tips: should use 'len' when loop the returned max sub array, so that it could also work for empty sub array, */ public static int[] findIncludeNonPositive(int[] arr) { if (arr.length == 0) return new int[]{0, 0, 0}; // empty array, no sub array, int maxSum = arr[0]; // max sum, found so far, int maxStart = 0; // start of max sum, int maxLen = 1; // length of max subarray, int sum = arr[0]; // current sum, int start = 0; // current start, for (int i = 1; i < arr.length; i++) { if (sum <= 0) { // should restart, start = i; sum = arr[i]; } else sum += arr[i]; if (sum > maxSum) { // get a larger sum, maxSum = sum; maxStart = start; maxLen = i - start + 1; } } return new int[]{maxSum, maxStart, maxLen}; } }
MaxSubSumTest.java:
(Test case, via TestNG )
import org.testng.Assert; import org.testng.annotations.Test; import java.util.Arrays; public class MaxSubSumTest { @Test public void test_find() { Assert.assertTrue(Arrays.equals(MaxSubSum.find(new int[]{-2, -3, 4, -1, -2, 1, 5, -3}), new int[]{7, 2, 5})); // max sub array: {4, -1, -2, 1, 5} Assert.assertTrue(Arrays.equals(MaxSubSum.find(new int[]{12, 14, 0, -4, 61, -39}), new int[]{83, 0, 5})); // max sub array: {12, 14, 0, -4, 61} // corner Assert.assertTrue(Arrays.equals(MaxSubSum.find(new int[]{}), new int[]{0, 0, 0})); // empty array, Assert.assertTrue(Arrays.equals(MaxSubSum.find(new int[]{-5, -4, 0, 0, -7, 0, -2}), new int[]{0, 0, 0})); // array with all elements <= 0, Assert.assertTrue(Arrays.equals(MaxSubSum.find(new int[]{-5, -4, -2, -7, -2, -9}), new int[]{0, 0, 0})); // array with all elements < 0, } @Test public void test_findIncludeNonPositive() { Assert.assertTrue(Arrays.equals(MaxSubSum.findIncludeNonPositive(new int[]{-2, -3, 4, -1, -2, 1, 5, -3}), new int[]{7, 2, 5})); // max sub array: {4, -1, -2, 1, 5} Assert.assertTrue(Arrays.equals(MaxSubSum.findIncludeNonPositive(new int[]{12, 14, 0, -4, 61, -39}), new int[]{83, 0, 5})); // max sub array: {12, 14, 0, -4, 61} // corner Assert.assertTrue(Arrays.equals(MaxSubSum.findIncludeNonPositive(new int[]{}), new int[]{0, 0, 0})); // empty array, Assert.assertTrue(Arrays.equals(MaxSubSum.findIncludeNonPositive(new int[]{-5, -4, 0, 0, -7, 0, -2}), new int[]{0, 2, 1})); // array with all elements <= 0, Assert.assertTrue(Arrays.equals(MaxSubSum.findIncludeNonPositive(new int[]{-5, -4, -2, -7, -2, -9}), new int[]{-2, 2, 1})); // array with all elements < 0, } }
Explanation:
find()
Find the maximum subarray, include only the subarray with a positive sum.
Behavior:
- For an array that contains only non-positive elements, an empty sub-array will be selected, starting at 0.
- For an empty input array, select an empty subarray starting at 0.
BTW:
- It is restarted only when a positive item is received, and the sum is <= 0.
findIncludeNonPositive()
Find the maximum nested array, also include the nested array with a non-positive sum.
Behavior:
- For an array that contains only non-positive elements, I will select the first smallest element.
- For an empty input array, select an empty subarray starting at 0.
BTW:
- It restarts whenever the previous sum is <= 0.
- He prefers the subarray to start at a lower index when there are several maximum subarrays.
- It will not contain unnecessary
0 at the end of the subarray, which does not change the amount.
Complexity: