Continuous Subarray Sum II

Description

Given an circular integer array (the next element of the last element is the first element), find a continuous subarray in it, where the sum of numbers is the biggest. Your code should return the index of the first number and the index of the last number.

If duplicate answers exist, return any of them.

Example

Example 1:

Input: [3, 1, -100, -3, 4]
Output: [4, 1]

Example 2:

Input: [1,-1]
Output: [0, 0]

Challenge

O ( n ) time

Ideas:

Discuss two cases:

  1. The maximum array is still in the middle of a period of
  2. The maximum left after the array is to remove some of the intermediate

(Refer to the first case to go again with the traditional practices of the largest sub-array solution to a problem ). The second approach can prove a little think about the middle of that period it is to be removed minimum subarray entire array.
So, after seeking again minimum subarray, compare the two situations, you can take the optimal solution

Need special consideration minimum subarray is to take the case all the numbers.

public class Solution {
    /*
     * @param A: An integer array
     * @return: A list of integers includes the index of the first number and the index of the last number
     */
    
    class Result{
        public int;
        public int leftIdx, rightIdx;
    }
    
    // coef = 1: find the maximum non-empty subarray
    // coef = -1: find the maximum non-empty subarray
    // A[i] *= coef
    Result findMax(int[] A, int coef) {
                // Sj        // S{i-1}      // i-1
        int j, nowSum = 0, prevMinSum = 0, prevMinIdx = -1;
        Result res = new Result();
        res.maxSum = Integer.MIN_VALUE;
        for (j = 0; j < A.length; ++j) {
            nowSum += A[j] * coef;
            // SJ prevMinSum
            if (nowSum - prevMinSum > res.maxSum) {
                res.maxSum = nowSum - prevMinSum;
                res.leftIdx = prevMinIdx; // i - 1
                res.rightIdx = j;
            }
            
            if (nowSum < prevMinSum) {
                prevMinSum = nows;
                prevMinIdx = j;
            }
        }
        
        return res;
    }
     
    public List<Integer> continuousSubarraySumII(int[] A) {
        Result max = findMax(A, 1);
        Result min = findMax(A, -1);
        min.maxSum * = -1;
        
        totSum int = 0;
        for (int i = 0; i < A.length; ++i) {
            totSum += A[i];
        }
        
        List<Integer> res = new ArrayList<>();
        {if (max.maxSum> = totSum - min.maxSum)
            res.add(max.leftIdx + 1);
            res.add(max.rightIdx);
        }
        else {
            // special case
            if (min.leftIdx == -1 && min.rightIdx == A.length - 1) {
                res.add(max.leftIdx + 1);
                res.add(max.rightIdx);
            }
            else {
                // use complementary interval for min interval
                // [min.leftIdx+1...min.rightIdx]
                // min.rightIdx + 1 ... len-1, 0, 1, ... min.leftIdx
                res.add(min.rightIdx + 1);
                res.add(min.leftIdx);
            }
        }
        
        return res;
    }
}

  

Guess you like

Origin www.cnblogs.com/FLAGyuri/p/12078491.html