对于给定的n个数字序列,找到具有最大总和的子字符串,其具有尽可能最低的计算复杂度

时间:2015-03-23 13:20:45

标签: c++ algorithm

任务:对于给定的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;
}

2 个答案:

答案 0 :(得分:3)

解决此任务的最佳计算复杂性是线性的。另一方面,您的代码不是线性的,因此您的问题的答案是 - 是的,有可能以更好的复杂性解决问题。

您正在解决的问题被称为Maximum subarray problem并且非常有名。

答案 1 :(得分:1)

看起来你直接编写代码。

第一步是考虑问题。

最佳序列可能包括第一个数字20.如果您从头开始检查数字,如果序列从20开始,序列可能会以最佳结果结束?那么你可以说任何更长的最佳序列都不能包含数字20?

如果您查看序列并逐一检查,您将看到20 + 8973可能是最佳的。最高3405不是最佳,但可能是最佳序列的开始。但是对于-9853,显然除了20 + 8973之外的最佳序列必须从3294或更晚开始。 (问问自己为什么,然后把它变成算法)。