任务:对于给定的n个数字序列,找到具有最大总和的子字符串。我用C ++创建了代码,给出了正确的答案。我想知道有没有可能以较低的计算复杂度来解决这个问题? 示例输入:
20
8973
-4625
-2038
3405
-7004
-9853
-361
3294
4036
8767
1711
-3100
2139
-4993
-9572
3789
2472
-6170
5408
2200
输出:
17808
我的实际代码:
#include<iostream>
#include<cmath>
#include<vector>
#include <algorithm>
using namespace std;
typedef long long int lint;
int main()
{
lint t = 0;
cin >> t;
vector<lint> Ar;
bool st = false;
for (lint i = 0; i < t; i++)
{
lint n = 0;
cin >> n;
if (st == true)Ar.push_back(n);
else if (n>0 && st == false)
{
Ar.push_back(n);
st = true;
}
}
if (Ar.size() == 0)
{
cout << "0" << endl;
}
else
{
vector<lint> Adding;
for (std::size_t i = 0; i < Ar.size(); i++)
{
if (Ar[i] > 0)
{
Adding.push_back(i);
}
}
vector<lint> D;
for (std::size_t j = 0; j < Adding.size(); j++)
{
lint s = 0;
for (std::size_t i = Adding[j]; i < Ar.size(); i++)
{
if (Ar[i] > 0)
{
s += Ar[i];
D.push_back(s);
}
else
{
s += Ar[i];
}
}
}
vector<lint>::const_iterator it2;
// Find max element in the vector
it2 = max_element(D.begin(), D.end());
cout << *it2 << endl;
}
return 0;
}
答案 0 :(得分:3)
解决此任务的最佳计算复杂性是线性的。另一方面,您的代码不是线性的,因此您的问题的答案是 - 是的,有可能以更好的复杂性解决问题。
您正在解决的问题被称为Maximum subarray problem并且非常有名。
答案 1 :(得分:1)
看起来你直接编写代码。
第一步是考虑问题。
最佳序列可能包括第一个数字20.如果您从头开始检查数字,如果序列从20开始,序列可能会以最佳结果结束?那么你可以说任何更长的最佳序列都不能包含数字20?
如果您查看序列并逐一检查,您将看到20 + 8973可能是最佳的。最高3405不是最佳,但可能是最佳序列的开始。但是对于-9853,显然除了20 + 8973之外的最佳序列必须从3294或更晚开始。 (问问自己为什么,然后把它变成算法)。