2.17 给出有效的算法(及其运行时间分析) 来:
a. 找出最小子序列和。
b. 找出最小的正子序列和。
c. 找出最大子序列乘积。
#include <iostream>
#include <string>
#include <vector>
using namespace std;
/*
* 最大子序列 ,复杂度: O(N^3)
*/
int maxSubSum1(const vector<int> & a)
{
int maxSum = 0;
for (size_t i=0;i<a.size(); ++i)
for (size_t j = i; j < a.size(); ++j)
{
int thisSum = 0;
for (size_t k = i; k <= j; ++k)
thisSum += a[k];
if (thisSum > maxSum)
maxSum = thisSum;
}
return maxSum;
}
/*
* 最大子序列 O(N^2)
*/
int maxSubSum2(const vector<int> & a)
{
int maxSum = 0;
for (size_t i = 0; i < a.size(); ++i)
{
int thisSum = 0;
for (size_t j = i; j < a.size(); ++j)
{
thisSum += a[j];
if (thisSum > maxSum)
maxSum = thisSum;
}
}
return maxSum;
}
/*
* 复杂度: O(N*logN)
*相连最大子序列和的递归算法 ,用到了分治的思想
*找出生成[left..right] 的子数组中的最大和
*不试图保留具体的最佳序列
*/
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;
}
int maxBorderSum = maxLeftBorderSum + maxRightBorderSum;
return maxLeftSum > maxRightSum ? (maxLeftSum > maxBorderSum ? maxLeftSum : maxBorderSum) :
(maxRightSum > maxBorderSum ? maxRightSum : maxBorderSum);
}
int maxSubSum3(const vector<int> & a)
{
return maxSumRec(a, 0, a.size() - 1);
}
/*
*复杂度:O(N)
*最优求子序列最大和的方法
*/
int maxSubSum4(const vector<int> & a)
{
int maxSum = 0, thisSum = 0;
for (size_t j = 0; j < a.size(); ++j)
{
thisSum += a[j];
if (thisSum > maxSum)
maxSum = thisSum;
/*任何最大子序列不可能从负数累加*/
else if (thisSum < 0)
thisSum = 0;
}
return maxSum;
}
/*
* O(N)
* 最小的子序列和。
*/
int minSubSum(const vector<int> & a)
{
int minSum = 0, thisSum = 0;
for (size_t j = 0; j < a.size(); ++j)
{
thisSum += a[j];
if (thisSum < minSum)
minSum = thisSum;
else if (thisSum > 0)
thisSum = 0;
}
return minSum;
}
/*
*最小正子序列和
* O(N)
*/
int minPositiveSubSum(const vector<int> & a)
{
int minSum = 0x7FFFFFFF, thisSum = 0;
for (size_t j = 0; j < a.size(); ++j)
{
thisSum += a[j];
if (thisSum < minSum && thisSum > 0)
minSum = thisSum;
else if (thisSum < 0)
thisSum = 0;
}
return minSum;
}
/*
*最大正子序列乘积
* O(N)
*/
int maxPositiveSubMul(const vector<int> & a)
{
int maxMul = 1, thisSum = 1;
for (size_t j = 0; j < a.size(); ++j)
{
thisSum *= a[j];
if (thisSum > maxMul && thisSum > 0)
maxMul = thisSum;
else if (thisSum < 0)
thisSum = 1;
}
return maxMul;
}
int main()
{
vector <int> souc = { 4,-3,5,-2,-1,2,6,-2,4,5,-8,6 };
cout << "maxSubSum1: " << maxSubSum1(souc) << endl;
cout << "maxSubSum2: " << maxSubSum2(souc) << endl;
cout << "maxSubSum3: " << maxSubSum3(souc) << endl;
cout << "maxSubSum4: " << maxSubSum4(souc) << endl;
cout << "minSubSum: " << minSubSum(souc) << endl;
cout << "minPositiveSubSum: " << minPositiveSubSum(souc) << endl;
cout << "maxPositiveSubMul: " << maxPositiveSubMul(souc) << endl;
return 0;
}