解法1:
可以将这个数组复制一段接在原数组的后面,然后分别从1到n开始,进行普通子数组最大和的解法。但是这样时间复杂度为n^2。这题的数据量是30000,显然不行,所以应该考虑nlogn或者n的解法。
解法2:
分成两种情况,一是没有首尾相连,就用正常求最大子数组和的方法。二是有首尾相连的情况,那么这种情况的解法就是将数组求和减去其中一段最小子数组和,但是这种需要考虑一种特殊情况,就是加入数组都小于0的话,这个思想的解法答案就是0,(因为最小子数组就等于这个数组)。
class Solution {
public:
int maxSubarraySumCircular(vector<int>& A) {
int ans=-2000000000;
int tmp=0;
for(auto num:A){
if(tmp>=0){
tmp+=num;
}
else{
tmp=num;
}
ans=max(ans,tmp);
}
int allsum=0; //数组的总长度
tmp=0;
int minsum=0; //最小子数组和
int f=0; //判断是否都小于0
for(auto num:A){
if(num>=0)
f=1;
allsum+=num;
if(tmp<=0){
tmp+=num;
}
else{
tmp=num;
}
minsum=min(minsum,tmp);
}
if(!f)
return ans;
return max(ans,allsum-minsum);
}
};