-1

I have a given array [-2 -3 4 -1 -2 1 5 -3] so the largest sum would be 7 (numbers from 3rd to 7th index). This array is just a simple example, the program should be user input elements and length of the array.

My question is, how to determine which sum would be largest?
I created a sum from all numbers and the sum of only positive numbers and yet the positive sum would be great but I didn't used the -1 and -2 after that 3rd index because of the "IF statement" so my sum is 10 and the solution is not good.

PaskoB
  • 13
  • 3
  • You can try to understand possible algorithmic approaches from tutorial sites [e.g.](https://www.geeksforgeeks.org/maximum-subarray-sum-using-divide-and-conquer-algorithm/). – Paul Rooney Mar 26 '19 at 00:07
  • 2
    Anything tagged both C and C++ is unlikely to be well-received here. –  Mar 26 '19 at 00:08
  • 1
    What is a "best sum" defined as? Please be more specific about what you really want to accomplish. – Remy Lebeau Mar 26 '19 at 00:08
  • If you require a time complexity of `O(N)` then you'll need solve this using dynamic programming techniques. – paddy Mar 26 '19 at 00:16
  • 2
    Can you post the code of what you have tried until now? (Please post it directly in the question, no images). – mamg22 Mar 26 '19 at 00:17
  • @NeilButterworth There are times when it's appropriate, but in this case I'd say *neither* language tag is needed since this seems to be about algorithm design and fairly language-agnostic. – Daniel H Mar 26 '19 at 00:18
  • Sounds like you want something on this general order, perhaps? https://stackoverflow.com/q/10464963/179910 – Jerry Coffin Mar 26 '19 at 00:21
  • Take all possible ranges, evaluate. Sort. Done. – tadman Mar 26 '19 at 00:28

2 Answers2

1

I assume your questions is to find the contiguous subarray(containing at least one number) which has the largest sum. Otherwise, the problem is pretty trivial as you can just pick all the positive numbers.

There are 3 solutions that are better than the O(N^2) brute force solution. N is the length of the input array.

  1. Dynamic programming. O(N) runtime, O(N) space

Since the subarray contains at least one number, we know that there are only N possible candidates: subarray that ends at A[0], A[1]...... A[N - 1] For the subarray that ends at A[i], we have the following optimal substructure: maxSum[i] = max of {maxSum[i - 1] + A[i], A[i]};

class Solution {
    public int maxSubArray(int[] nums) {
        int max = Integer.MIN_VALUE;
        if(nums == null || nums.length == 0) {
            return max;
        }
        int[] maxSum = new int[nums.length + 1];
        for(int i = 1; i < maxSum.length; i++) {
            maxSum[i] = Math.max(maxSum[i - 1] + nums[i - 1], nums[i - 1]);
        }
        for(int i = 1; i < maxSum.length; i++) {
            max = Math.max(maxSum[i], max);
        }
        return max;
    }
}
  1. Prefix sum, O(N) runtime, O(1) space

Maintain a minimum sum variable as you iterate through the entire array. When visiting each number in the input array, update the prefix sum variable currSum. Then update the maximum sum and minimum sum shown in the following code.

class Solution {
    public int maxSubArray(int[] nums) {
        if(nums == null || nums.length == 0) {
            return 0;
        }
        int maxSum = Integer.MIN_VALUE, currSum = 0, minSum = 0;
        for(int i = 0; i < nums.length; i++) {
            currSum += nums[i];
            maxSum = Math.max(maxSum, currSum - minSum);
            minSum = Math.min(minSum, currSum);
        }
        return maxSum;
    }
}
  1. Divide and conquer, O(N * logN) runtime

Divide the original problem into two subproblems and apply this principle recursively using the following formula.

Let A[0,.... midIdx] be the left half of A, A[midIdx + 1, ..... A.length - 1] be the right half of A. leftSumMax is the answer of the left subproblem, rightSumMax is the answer of the right subproblem.

The final answer will be one of the following 3: 1. only uses numbers from the left half (solved by the left subproblem) 2. only uses numbers from the right half (solved by the right subproblem) 3. uses numbers from both left and right halves (solved in O(n) time)

class Solution {
    public int maxSubArray(int[] nums) { 
        if(nums == null || nums.length == 0)
        {
            return 0;
        }
        return maxSubArrayHelper(nums, 0, nums.length - 1);
    }
    private int maxSubArrayHelper(int[] nums, int startIdx, int endIdx){
        if(startIdx == endIdx){
            return nums[startIdx];
        }
        int midIdx = startIdx + (endIdx - startIdx) / 2;
        int leftMax = maxSubArrayHelper(nums, startIdx, midIdx);
        int rightMax = maxSubArrayHelper(nums, midIdx + 1, endIdx);
        int leftIdx = midIdx, rightIdx = midIdx + 1;
        int leftSumMax = nums[leftIdx], rightSumMax = nums[rightIdx];
        int leftSum = nums[leftIdx], rightSum = nums[rightIdx];
        for(int i = leftIdx - 1; i >= startIdx; i--){
            leftSum += nums[i];
            leftSumMax = Math.max(leftSumMax, leftSum);
        }
        for(int j = rightIdx + 1; j <= endIdx; j++){
            rightSum += nums[j];
            rightSumMax = Math.max(rightSumMax, rightSum);
        }
        return Math.max(Math.max(leftMax, rightMax), leftSumMax + rightSumMax);
    }
}
Lyn
  • 637
  • 5
  • 16
0

Try this:

  1. locate the first positive number, offset i.
  2. add the following positive numbers, giving a sum of sum, last offset is j. If this sum is greater than your current best sum, it becomes the current best sum with offsets i to j.
  3. add the negative numbers that follow until you get another positive number. If this negative sum is greater in absolute value than sum, start a new sum at this offset, otherwise continue with the current sum.
  4. go back to step 2.

Stop this when you get to the end of the array. The best positive sum has been found.

If no positive sum can be found, locate the least negative value, this single entry would be your best non-trivial sum.

chqrlie
  • 131,814
  • 10
  • 121
  • 189