#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
//求子数组的最小和
//利用的是dp的思想,依次遍历数组中的每个元素,把他们相加,如果加起来大于0,则
//把当前元素之和清为0,否则则和最小和比较,更新最小和,最后得到必是子数组的最小和
//时间复杂度:o(n) 空间复杂度:o(1)
int minSum(vector<int> &num)
{
int min_sum = 0, sum = 0;
for(int i=0; i<num.size(); i++)
{
sum += num[i];
if(sum > 0) sum = 0;
if(sum < min_sum)
min_sum = sum;
}
if(min_sum == 0) //数组中只有正数
{
min_sum = num[0];
for(int i=1; i<num.size(); i++)
{
if(num[i]<min_sum)
min_sum = num[i];
}
}
return min_sum;
}
//求子数组的最大和
//利用的是dp的思想,依次遍历数组中的每个元素,把他们相加,如果加起来小于0,则
//把当前元素之和清为0,否则则和最大和比较,更新最大和,最后得到必是子数组的最大和
//时间复杂度:o(n)
int maxSum(vector<int> &num)
{
int max_sum = 0, sum = 0;
for(int i=0; i<num.size(); i++)
{
sum += num[i];
if(sum < 0) sum = 0;
if(sum > max_sum)
max_sum = sum;
}
if(max_sum == 0) //数组中只有负数
{
max_sum = num[0];
for(int i=1; i<num.size(); i++)
{
if(num[i]>max_sum)
max_sum = num[i];
}
}
return max_sum;
}
//求子数组的和的绝对值的最小值
//暴力穷举法
//时间复杂度:o(n^2) 空间复杂度:o(1)
int minAbsSum1(vector<int> &num)
{
int min_abs_sum = INT_MAX;
for(int i=0; i<num.size(); i++)
{
int cur_sum = 0;
for(int j=i; j<num.size(); j++)
{
cur_sum += num[j];
if(abs(cur_sum) < min_abs_sum)
min_abs_sum = abs(cur_sum);
}
}
return min_abs_sum;
}
//求子数组的和的绝对值的最小值
//先计算所有sum[0-j] 0<= j <n,然后对sum[0-j]的数组进行排序,那么对于任何i,j段的和等于:sum[i-j]= sum[0-j] - sum[0-i];
//设置数组sum用来存储子数组0-j的和
//因为已经对sum进行了排序,排序后只需要找到sum[z]-sum[z-1],sum[z] (0<=z<sum.size())的绝对值的最小值即可。z为排序后的索引
//如果是sum[z]情形,z为排序后的索引,则minAbs = abs(sum[0-i])
//如果是sum[z]-sum[z-1]情形,则minAbs = abs(sum[i]-sum[j])
//时间复杂度:o(nlogn) 空间复杂度:o(n)
int minAbsSum2(vector<int> &num)
{
if(num.size()==0) return 0;
if(num.size()==1) return abs(num[0]);
int min_abs_sum;
vector<int> sum;
int cur_sum = 0;
for(int i=0; i<num.size(); i++)
{
cur_sum += num[i];
if(cur_sum == 0)
return 0;
sum.push_back(cur_sum);
}
sort(sum.begin(), sum.end());
min_abs_sum = abs(sum[0]);
for(int i=0; i<sum.size()-1; i++)
{
int temp1 = abs(sum[i+1]);
int temp2 = abs(sum[i+1]-sum[i]);
cur_sum = (temp1<temp2)?temp1:temp2;
if(cur_sum == 0)
return 0;
if(cur_sum<min_abs_sum)
min_abs_sum = cur_sum;
}
return min_abs_sum;
}
//求子数组的和的绝对值的最da值
//暴力穷举法
//时间复杂度:o(n^2) 空间复杂度:o(1)
int maxAbsSum1(vector<int> &num)
{
int max_abs_sum = 0;
for(int i=0; i<num.size(); i++)
{
int cur_sum = 0;
for(int j=i; j<num.size(); j++)
{
cur_sum += num[j];
if(abs(cur_sum) > max_abs_sum)
max_abs_sum = abs(cur_sum);
}
}
return max_abs_sum;
}
//求子数组的和的绝对值的最大值
//先计算所有sum[0-j] 0<= j <n,然后对sum[0-j]的数组进行排序,那么对于任何i,j段的和等于:sum[i-j]= sum[0-j] - sum[0-i];
//设置数组sum用来存储子数组0-j的和
//因为已经对sum进行了排序,排序后只需要找到sum[sum.size()-1]-sum[0],sum[z] (0<=z<sum.size())的绝对值的最大值即可。z为排序后的索引
//如果是sum[z]情形,z为排序后的索引,则maxAbs = abs(sum[0-i])
//如果是sum[sum.size()-1]-sum[0]情形,则maxAbs = abs(sum[i]-sum[j])
//时间复杂度:o(nlogn) 空间复杂度:o(n)
int maxAbsSum2(vector<int> &num)
{
if(num.size()==0) return 0;
if(num.size()==1) return abs(num[0]);
int max_abs_sum;
vector<int> sum;
int cur_sum = 0;
for(int i=0; i<num.size(); i++)
{
cur_sum += num[i];
if(cur_sum == 0)
return 0;
sum.push_back(cur_sum);
}
sort(sum.begin(), sum.end());
max_abs_sum = abs(sum[sum.size()-1]-sum[0]);
for(int i=0; i<sum.size(); i++)
{
cur_sum = abs(sum[i]);
if(cur_sum>max_abs_sum)
max_abs_sum = cur_sum;
}
return max_abs_sum;
}
int main()
{
int n;
while(cin>>n)
{
vector<int> num;
int number;
for(int i=0; i<n; i++)
{
cin>>number;
num.push_back(number);
}
cout<<"minSum = "<<minSum(num)<<endl;
cout<<"maxSum = "<<maxSum(num)<<endl;
cout<<"minAbsSum1 = "<<minAbsSum1(num)<<endl;
cout<<"minAbsSum2 = "<<minAbsSum2(num)<<endl;
cout<<"maxAbsSum1 = "<<maxAbsSum1(num)<<endl;
cout<<"maxAbsSum2 = "<<maxAbsSum2(num)<<endl;
cout<<"------------------------------------"<<endl;
}
return 0;
}连续子数组的和的最大值、最小值以及和的绝对值的最大值、最小值
原文地址:http://blog.csdn.net/zuijinhaoma8/article/details/45290145