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 &lt;= k1, k2 &lt;= j with k1 % n == k2 % n.

&nbsp;
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.


&nbsp;
Constraints:


	n == nums.length
	1 &lt;= n &lt;= 3 * 104
	-3 * 104 &lt;= nums[i] &lt;= 3 * 104


class Solution:

    def kadanes(self,nums):

        #kadanes algo

        max_till_now = nums[0]
        curr_max = nums[0]

        for i in range(1,len(nums)):
            curr_max = max(curr_max+nums[i],nums[i])
            max_till_now = max(max_till_now,curr_max)

        return max_till_now

    def maxSubarraySumCircular(self, nums: List[int]) -> int:

        #there will be 2 case
        #case 1 : our max subarray is not wrapping i.e not circular
        #case 2: our max subarray is wrapping i.e circular

        # case 1 is easy to find
        # to find case 2 what we can do is if we multiply each nums element by -1 and
        # on that find kadanes then we will get sum of elements which is not part of maxsubarray in case2 (not part because we negate)
        # now subtract this newmax in case 2 from total nums sum, we get wrapping sum
        # max of case1 and case is our ans

        total = sum(nums)

        nonwrappingsum = self.kadanes(nums)

        # edge case when all elements are -ve then return max negative
        if nonwrappingsum<0:
            return nonwrappingsum

        #negate
        for i in range(len(nums)):
            nums[i]*=-1

        wrappingsum = total-(-self.kadanes(nums)) #-ve because originally it was negated

        return max(nonwrappingsum,wrappingsum)
class Solution {
    public int maxSubarraySumCircular(int[] nums) {
        int ans = kadane(nums);
        int sum = 0;
        for (int i = 0; i < nums.length; i++) {
            sum += nums[i];
            nums[i] = -nums[i];
        }
        int kadane_sum = kadane(nums) + sum;
        if (kadane_sum == 0) {
            return ans;
        }
        return Math.max(ans, kadane_sum);
    }
    public int kadane(int[] nums) {
        int sum = 0;
        int ans = Integer.MIN_VALUE;
        for (int i : nums) {
            sum += i;
            ans = Math.max(ans, sum);
            if (sum < 0) {
                sum = 0;
            }
        }
        return ans;
    }
}
class Solution {
public:
    int maxSubarraySumCircular(vector<int>& nums) {
        int n=nums.size();
    int currsummin=nums[0],ansmin=nums[0],currsummax=nums[0],ansmax=nums[0],sum=nums[0];
        for(int i=1;i<n;i++)
        {
            sum+=nums[i];
            
            currsummin=min(nums[i],currsummin+nums[i]);
            ansmin=min(ansmin,currsummin);
            
            currsummax=max(currsummax+nums[i],nums[i]);
            ansmax=max(ansmax,currsummax);
        }
        return ansmax>0 ? max(ansmax,sum-ansmin) : ansmax;
    }
};
/**
 * @param {number[]} nums
 * @return {number}
 */
var maxSubarraySumCircular = function(nums) {
    let n = nums.length;

    // Kadane for single interval
    let curr = nums[0]; // dp[j] Maximum sum subbarray till j
    let ans = nums[0]; // Maximum of all dps till j i.e. max(dp[0], dp[1], ... dp[i], ...dp[j]);

    for(let i = 1; i < n; i++) {
        curr = nums[i] + Math.max(0, curr);
        ans = Math.max(ans, curr);
    }

    /**
    * If we don't find answer using kadane using above logic then that means only one thing
    * some answer is present in 1st half and second in other half (since it is circular array)
    **/

    let rightSum = new Array(n); // Sum from Right, used to represent 2nd half of the solution

    rightSum[n - 1] = nums[n - 1];

    for(let i = n - 2; i >= 0; i--) {
        rightSum[i] = rightSum[i + 1] + nums[i];
    }

    let maxRightSum = new Array(n); // Used to fast fetch max right sum till given point
    maxRightSum[n - 1] = rightSum[n - 1];

    for(let i = n - 2; i >= 0; i--) {
        maxRightSum[i] = Math.max(maxRightSum[i + 1], rightSum[i]);
    }

    /**
    * Now solution is max of:
    * [Sum of [A0 --- Ai] + Maximum [Ai+2 --- An]]
    * Considering i + 1 will be equivalent to kadane which we already discussed above.
    **/
    let leftSum = 0;
    for(let i = 0; i < n - 2; i++) {
        leftSum += nums[i];
        ans = Math.max(ans, leftSum + maxRightSum[i + 2]);
    }
    return ans;

};
Maximum Sum Circular Subarray