求数列的最大子段和的两种方法(包括时间复杂度为线性时间的算法)

来源:互联网 发布:大数据imf 编辑:程序博客网 时间:2024/05/17 08:10

方法一:
C++代码:

#include <iostream>#include <vector>using namespace std;int max_sub_sum(const vector<int> &v, int &best_i, int &best_j){    int n = v.size();    //当前最大子段和    int sum = 0;    //当前字段和    int this_sum = 0;    int i,j;    for (i=0,j=0;j<n;++j)    {        this_sum += v[j];        if (this_sum >= sum)        {            sum = this_sum;            best_i = i;            best_j = j;        }        else if (this_sum < 0)        {            this_sum = 0;            i = j+1;        }    }    return sum;}int main(){    vector<int> v;    v.push_back(-1);    v.push_back(5);    v.push_back(-2);    v.push_back(-1);    v.push_back(4);    v.push_back(1);    v.push_back(-3);    v.push_back(1);    v.push_back(-2);    v.push_back(1);    /*v.push_back(1);    v.push_back(-2);    v.push_back(3);    v.push_back(10);    v.push_back(-4);    v.push_back(7);    v.push_back(2);    v.push_back(-5);*/    for (int i=0;i<v.size();++i)    {        cout<<v[i]<<' ';    }    cout<<endl;    int best_i=1;    int best_j=0;    int max_sum = max_sub_sum(v,best_i,best_j);    if (best_i > best_j)    {        cout<<"最大子段和为:"<<max_sum<<endl;    }    else    {        cout<<"最大子段和为:"<<max_sum<<endl;        cout<<"最大子段为:";        for (int i=best_i;i<=best_j;++i)        {            cout<<v[i]<<' ';        }    }    cout<<endl;    return 0;}

运行结果:
这里写图片描述
这里写图片描述

方法二:
分析:这种情况为二分法不独立的情况,子问题重叠。
C++源代码:

#include <iostream>#include <vector>#include <ctime>using namespace std;int max_sub_sum(vector<int> v,int i, int j){    if ( i == j)    {        if (v[i]>0)        {            return v[i];        }        return 0;    }    int mid = (i+j)/2;    int l_sub_sum = max_sub_sum(v,i,mid);    int r_sub_sum = max_sub_sum(v,mid+1,j);    int current_lsum = v[mid];    int max_lsum = v[mid];    for (int i=mid-1;i>=0;--i)    {        current_lsum += v[i];        if (current_lsum > max_lsum)        {            max_lsum = current_lsum;        }    }    int max_rsum = v[mid+1];    int current_rsum = v[mid+1];    for (int i=mid+2;i<=j;++i)    {        current_rsum += v[i];        if (current_rsum > max_rsum)        {            max_rsum = current_rsum;        }    }    int mid_sub_sum = max_lsum+max_rsum;    if (l_sub_sum>mid_sub_sum && l_sub_sum>r_sub_sum)    {        return l_sub_sum;    }    else if (mid_sub_sum>l_sub_sum && mid_sub_sum>r_sub_sum)    {        return mid_sub_sum;    }    return r_sub_sum;}int main(){    vector<int> v;    v.push_back(-1);    v.push_back(5);    v.push_back(-2);    v.push_back(-1);    v.push_back(4);    v.push_back(1);    v.push_back(-3);    v.push_back(1);    v.push_back(-2);    v.push_back(1);    for (int i=0;i<v.size();++i)    {        cout<<v[i]<<' ';    }    cout<<endl;    cout<<max_sub_sum(v,0,v.size()-1)<<endl;    return 0;}

测试结果:
这里写图片描述

0 0
原创粉丝点击