最大的子序列和问题
问题描述:最大的子序列和问题,给定(有可能负的整数)a1,a2,…,aN,求最大子序列和(为方便起见,如果所有整数均为负数,则最大子序列的和为0)
- 第一种算法
时间复杂度为O(N3)
int maxSubSum1( const vector<int> & a )
{
int maxSum = 0;
for(int i = 0; i < a.size(); ++i)
for(int j = i; j < a.size(); ++j)
{
int thisSum = 0;
for(int k = i; k <= j; ++k)
thisSum += a[k];
if(thisSum > maxSum)
maxSum = thisSum;
}
return maxSum;
}
2.第二种算法
时间复杂度O(N2)
int maxSubSum2(const vector<int> & a)
{
int maxSum = 0;
for(int i = 0;i < a.size(); ++i)
{
int thisSum = 0;
for(int j = 1;j < a.size(); ++j)
{
thisSum += a[j];
if(thisSum > maxSum)
maxSum = thisSum;
}
}
return maxSum;
}
3.第三种算法
时间复杂度为O(NlogN)
int maxSumRec(const vector<int> & a,int left, int right)
{
if(left == right)
if(a[left] > 0)
return a[left];
else
return 0;
int center = (left + right)/2;
int maxLeftSum = maxSumRec(a, left, center);
int maxRightSum = maxSumRec(a, center+1, right);
int maxLeftBorderSum = 0,leftBorderSum = 0;
for(int i = center; i >= left; --i)
{
leftBorderSum += a[i];
if(leftBorderSum > maxLeftBorderSum)
maxLeftBorderSum = leftBorderSum;
}
int maxRightBorderSum = 0,rightBorderSum = 0;
for(int j = center+1; j <= right; ++j)
{
rightBorderSum += a[j];
if(rightBorderSum > maxRightBorderSum)
maxRightBorderSum = rightBorderSum;
}
return (maxLeftSum, maxRightSum,
maxLeftBorderSum + maxRightBorderSum);
}
int maxSubSum3(const vector<int> & a)
{
return maxSumRec(a, 0, a.size()-1);
}
4.第四种算法
int maxSubSum4(const vector<int> & a)
{
int maxSum = 0, thisSum = 0;
for(int j = 0; j < a.size(); ++j)
{
thisSum += a[j];
if(thisSum > maxSum)
maxSum = thisSum;
else
if(thisSum < 0)
thisSum = 0;
}
return maxSum;
}
这里是自己测试算法的程序源码
#include<iostream>
#include<vector>
#include<algorithm>
#include<math.h>
#include<string>
using namespace::std;
//最大的子序列和问题
//给定(有可能负的整数)a1,a2,...,aN,求最大子序列和
//(为方便起见,如果所有整数均为负数,则最大子序列的和为0)
//第一种算法
//遍历全部
//时间复杂度最大
int maxSubSum1( const vector<int> & a )
{
int maxSum = 0;
for(int i = 0; i < a.size(); ++i)
for(int j = i; j < a.size(); ++j)
{
int thisSum = 0;
for(int k = i; k <= j; ++k)
thisSum += a[k];
if(thisSum > maxSum)
maxSum = thisSum;
}
return maxSum;
}
//第二种算法
//改进的第一种算法
//但是还不知道为什么 结果有一些问题
int maxSubSum2(const vector<int> & a)
{
int maxSum = 0;
for(int i = 0;i < a.size(); ++i)
{
int thisSum = 0;
for(int j = 1;j < a.size(); ++j)
{
thisSum += a[j];
if(thisSum > maxSum)
maxSum = thisSum;
}
}
return maxSum;
}
//第三种算法
//分为左右分别计算
//利用递归计算 此时假设数组大小是个偶数
int maxSumRec(const vector<int> & a,int left, int right)
{
if(left == right)
if(a[left] > 0)
return a[left];
else
return 0;
int center = (left + right)/2;
int maxLeftSum = maxSumRec(a, left, center);
int maxRightSum = maxSumRec(a, center+1, right);
int maxLeftBorderSum = 0,leftBorderSum = 0;
for(int i = center; i >= left; --i)
{
leftBorderSum += a[i];
if(leftBorderSum > maxLeftBorderSum)
maxLeftBorderSum = leftBorderSum;
}
int maxRightBorderSum = 0,rightBorderSum = 0;
for(int j = center+1; j <= right; ++j)
{
rightBorderSum += a[j];
if(rightBorderSum > maxRightBorderSum)
maxRightBorderSum = rightBorderSum;
}
return (maxLeftSum, maxRightSum,
maxLeftBorderSum + maxRightBorderSum);
}
int maxSubSum3(const vector<int> & a)
{
return maxSumRec(a, 0, a.size()-1);
}
//第四种算法
int maxSubSum4(const vector<int> & a)
{
int maxSum = 0, thisSum = 0;
for(int j = 0; j < a.size(); ++j)
{
thisSum += a[j];
if(thisSum > maxSum)
maxSum = thisSum;
else
if(thisSum < 0)
thisSum = 0;
}
return maxSum;
}
int main()
{
int abc[10] = {1, 2, 5, -5, 9, -11, 29, 4, 7, 2};
std::vector<int> vector_abc(abc, abc+10);
int Sum = maxSubSum4(vector_abc);
cout<< Sum << endl;
}