# 918. Maximum Sum Circular Subarray

Given a **circular integer array** `nums` of length `n`, return *the maximum possible sum of a non-empty **subarray** of* `nums`.

A **circular array** means the end of the array connects to the beginning of the array. Formally, the next element of `nums[i]` is `nums[(i + 1) % n]` and the previous element of `nums[i]` is `nums[(i - 1 + n) % n]`.

A **subarray** may only include each element of the fixed buffer `nums` at most once. Formally, for a subarray `nums[i], nums[i + 1], ..., nums[j]`, there does not exist `i <= k1`, `k2 <= j` with `k1 % n == k2 % n`.

&#x20;

**Example 1:**

```
Input: nums = [1,-2,3,-2]
Output: 3
Explanation: Subarray [3] has maximum sum 3.
```

**Example 2:**

```
Input: nums = [5,-3,5]
Output: 10
Explanation: Subarray [5,5] has maximum sum 5 + 5 = 10.
```

**Example 3:**

```
Input: nums = [-3,-2,-3]
Output: -2
Explanation: Subarray [-2] has maximum sum -2.
```

&#x20;

**Constraints:**

* `n == nums.length`
* `1 <= n <= 3 * 104`
* `-3 * 104 <= nums[i] <= 3 * 104`

### Solution:

<https://www.jiuzhang.com/problem/maximum-sum-circular-subarray/><br>

What is an alternate way of representing a circular array so that it appears to be a straight array? Essentially, there are two cases of this problem that we need to take care of. Let's look at the figure below to understand those two cases:\
![](https://assets.leetcode.com/uploads/2019/10/20/circular_subarray_hint_1.png)

Case 1:   #### case 1: max appear in the middle

Answer is in (LeetCode 53 Maximum Subarray)

Case 2:  #### case 2: max appear at two ends, so in the middle is min ,

Find MaxSubArray, sumArray- MinSubArray  (注意这里要判断sumArray != MinSubArray)

```
class Solution {
    public int maxSubarraySumCircular(int[] nums) {
    
        // case 1:
        int case1 = maxSubArray(nums);
        //case 2:
        int case2 = sumArray(nums) - minSubArray(nums);
        if(case2 != 0)
        {
            return Math.max(case1, case2);
        }
        
        return case1;
        
    }
    
    public int sumArray(int[] nums)
    {
        int sum = 0;
        for(int i = 0; i< nums.length; i++)
        {
            sum+=nums[i];
        }
        return sum;
    }
    
    public int maxSubArray(int[] nums)
    {
        int n = nums.length;
        int[] dp = new int[n+1];
        dp[0] = Integer.MIN_VALUE;
        for(int i=1; i<= n; i++)
        {
            if(dp[i-1] < 0)
            {
                dp[i] = nums[i-1];
            }
            else
            {
                dp[i] = dp[i-1]+nums[i-1];
            }
        }
        int result = Integer.MIN_VALUE;
        for(int i = 0; i<=n ; i++)
        {
            result = Math.max(result, dp[i]);
        }
        return result;
    }
    
    public int minSubArray(int[] nums)
    {
        int n = nums.length;
        int[] dp = new int[n+1];
        dp[0] = Integer.MAX_VALUE;
        for(int i = 1; i<= n; i++)
        {
            if(dp[i-1] > 0)
            {
                dp[i] = nums[i-1];
            }
            else
            {
                dp[i] = dp[i-1]+nums[i-1];
            }
        }
        int result = Integer.MAX_VALUE;
        for(int i = 0; i<=n ; i++)
        {
            result = Math.min(result, dp[i]);
        }
        return result;
    }
}
```
