Algorithm Of Maximum Subarry (利用分治法求最大子数组问题)

1. 暴力法求解,复杂度 n2

#include<bits/stdc++.h>
using namespace std;
const int maxn=1007;
int A[maxn];
int main(){
    int n;
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>A[i];
    }
    int max_i,max_j;        //记录最大子数组区间
    int sum=0,max_sum=0;
    for(int i=1;i<=n;i++){
            sum=A[i];
        for(int j=i+1;j<=n;j++){
            sum+=A[j];
            if(sum>max_sum){
                max_sum=sum;
                max_i=i;
                max_j=j;
            }
        }
    }
    cout<<max_sum<<" "<<max_i<<" "<<max_j<<endl;
    //cout<<find_maximum_subarry(A,1,n);
    return 0;
}

2.利用分治法求解,nlogn

#include<bits/stdc++.h>
using namespace std;
const int maxn=1007;
int A[maxn];
const int _inf=0xc0c0c0c0;      //负无穷
/*
利用分治法求最大连续子数组问题
子数组的位置上一定位于: ①A[low,mid],②A[mid+1,high],③A[low,high](跨越了中点);
分解:
解决:
合并:将第三种子问题划分为合并
*/

//第三种情况,一定是左子数组最大值加上右子数组最大值,且经过中点
int find_max_corssing_subbary(int *A,int low,int mid,int high){
    int left_sum=_inf;
    int right_sum=_inf;
    int sum=0;
    //求左子数组最大值
    for(int i=mid;i>=low;i--){
        sum+=A[i];
        if(sum>left_sum){
            left_sum=sum;
        }
    }
    sum=0;
    //求右子数组最大值
    for(int j=mid+1;j<=high;j++){
        sum+=A[j];
        if(sum>right_sum){
            right_sum=sum;
        }
    }
    return (left_sum+right_sum);


}

int find_maximum_subarry(int *A,int low,int high){
    if(low==high){
        return A[high];
    }
    else{
        int mid=(low+high)/2;
        int left_sum=find_maximum_subarry(A,low,mid);
        int right_sum=find_maximum_subarry(A,mid+1,high);
        //合并过程
        int corss_sum=find_max_corssing_subbary(A,low,mid,high);
        int _sum=max(left_sum,max(right_sum,corss_sum));
        return _sum;
    }

}

int main(){
    int n;
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>A[i];
    }

    cout<<find_maximum_subarry(A,1,n);
    return 0;
}

发布了40 篇原创文章 · 获赞 9 · 访问量 3303

猜你喜欢

转载自blog.csdn.net/weixin_44706647/article/details/99709876