今天遇到一个问题,数组连续子序列
类似leetcode 53 但略微不同,是循环数组
如果一个数组 [-2,1,-3,4,-1,2,1,-5,4] 返回连续子数组最大和
方法一,暴力循环,复杂度较高,不多介绍
方法二,贪心法
int main()
{
vector<int>arr;
//输入数据
int m;
cin>>m;
for(int i=0;i<m;i++)
{
int tmp;
cin>>tmp;
arr.push_back(tmp);
}
//贪心
int result = INT_MIN;
int sum=0;
for(int i=0;i<arr.size();i++)
{
sum+=arr[i];
result = max(sum,result);
//小于0重新判断大小
if(sum<0)
{
sum=0;
}
}
cout<<result<<endl;
return 0;
}
这样解决很常见,但遇到的问题是循环数组,可以从尾部到头部寻找最大和
举例,输入[4,-3,2,-6,2] 最大和是尾部 2 和头部 4 的和 。解
解决方法
将数组重复拼接到尾部,分别使用上面的方法求出,0 ~ n,1 ~ n+1,2 ~ n+2,...,n-1 ~ 2*n-1 最大和,取其中最大的。
复杂度o(n2)复杂度过高,看到有一个解法,是求出最大和maxsum,最小和minsum,数组总和sum。
结果为max(maxsum,(sum-minsum));
代码如下:
#include<iostream>
#include<vector>
using namespace std;
int main()
{
vector<int>arr;
//输入数据
int arrsum=0;
int m;
cin>>m;
for(int i=0;i<m;i++)
{
int tmp;
cin>>tmp;
arrsum+=tmp;
arr.push_back(tmp);
}
//贪心
int result = INT_MIN;
int sum=0;
for(int i=0;i<arr.size();i++)
{
sum+=arr[i];
result = max(sum,result);
//小于0重新判断大小
if(sum<0)
{
sum=0;
}
}
//求出最小值
int minresult = INT_MAX;
int minsum = 0;
for(int i=0;i<arr.size();i++)
{
minsum+=arr[i];
minresult = min(minresult,minsum);
if(minsum>0)
{
minsum = 0;
}
}
int maxout=0;
//循环数组的最大和为 max(最大和,总和-最小和)
maxout = max(result,(arrsum-minresult));
cout<<maxout<<endl;
return 0;
}
其他方法待续