首页 > 其他 > 详细

最大子列和求解

时间:2019-10-31 22:37:53      阅读:69      评论:0      收藏:0      [点我收藏+]

题目如下:

技术分享图片

技术分享图片

四种解题思路对应的完整代码如下:

//最大子列和求解思路

#include<iostream>
#include<cstdio>
using namespace std;
int maxsubseqsum1(int nums[],int size);

int maxsubseqsum2(int nums[],int size);

int maxsubseqsum3(int nums[],int size);

int maxsubseqsum4(int nums[],int size);

void begin();

int main() {
    int switchflag=1;
    while(switchflag==1){
        begin();
        cout<<"输入1继续下一次计算,输入其他按键退出:";
        cin>>switchflag;
    }
    exit(1);
}

void begin(){
    int size,i;
    int maxsum;
    cout<<"请输入整数个数(1-100):";
    cin>>size;
    while(size<1||size>100) {
        cout<<"请输入1-100范围内的整数:";
        cin>>size;
    }
    int nums[size];
    for(i=0;i<size;i++){
        cout<<"请输入第"<<i+1<<"个整数:";
        cin>>nums[i];
    }
    maxsum = maxsubseqsum1(nums,size);
    cout<<"思路一:"<<maxsum<<endl;

    maxsum = maxsubseqsum2(nums,size);
    cout<<"思路二:"<<maxsum<<endl;

    maxsum = maxsubseqsum3(nums,size);
    cout<<"思路三:"<<maxsum<<endl;

    maxsum = maxsubseqsum4(nums,size);
    cout<<"思路四:"<<maxsum<<endl;
} 

//思路一,左边界i,右边界j,确定范围之后,再遍历i...j求和,时间复杂度T(n) =O(n^3)
int maxsubseqsum1(int nums[],int size) {
    int i,j,k;
    int sum,thissum;
    sum=0;
    //子列的左边 0.....size-1
    for(i=0; i<size; i++) {
        //子列的右边 i....size-1
        for(j=i; j<size; j++) {
            thissum=0;
            //循环累加求和i...j
            for(k=i; k<=j; k++) {
                thissum+=nums[k];
            }
            if(thissum>sum) {
                sum=thissum;
            }
        }

    }
    return sum;
}

//基于思路一进行改进,每次右边界右移一个单位时,不再重新开始累加求和,直接在之前的基础上累加,也就是同一个左边界i,对于右边界j右移时,计算一次加法运算即可
//时间复杂度T(n)=O(n^2)
int maxsubseqsum2(int nums[],int size) {
    int i,j;
    int sum,thissum;
    sum=0;
    //子列的左边 0.....size-1
    for(i=0; i<size; i++) {
        //子列的右边 i....size-1
        thissum=0;//同一个左边界i
        for(j=i; j<size; j++) {
            thissum+=nums[j];
            //循环累加求和i...j

            if(thissum>sum) {
                sum=thissum;
            }
        }

    }
    return sum;
}

//返回3个整数中的最大的一个
int getmaxint3(int a,int b,int c) {
    return a>b?(a>c?a:c):(b>c?b:c);
}

//递归调用分治思想的核心代码
int dividegovern(int nums[],int left,int right) {
    //左右最大子列和
    int MaxLeftSum, MaxRightSum;
    
    //跨边界左右最大子列和
    int MaxLeftBorderSum, MaxRightBorderSum;
    
    //当前计算的左右边界子列和
    int LeftBorderSum, RightBorderSum;
    
    int center, i;

    //递归调用终止条件,子列只有一个元素
    if( left == right )  {
        if( nums[left] > 0 )  return nums[left];
        else return 0;
    }

    //先分
    center = ( left + right ) / 2; 
    //递归调用获取左边最大子列和 left.....center 
    MaxLeftSum = dividegovern( nums, left, center );
    
    //递归调用获取右边最大子列和 center+1.....right
    MaxRightSum = dividegovern( nums, center+1, right );

    //跨边界最大子列和 
    MaxLeftBorderSum = 0;
    LeftBorderSum = 0;
    for( i=center; i>=left; i-- ) { /* 从中线向左扫描 */
        LeftBorderSum += nums[i];
        if( LeftBorderSum > MaxLeftBorderSum )
            MaxLeftBorderSum = LeftBorderSum;
    } /* 左边扫描结束 */

    MaxRightBorderSum = 0;
    RightBorderSum = 0;
    for( i=center+1; i<=right; i++ ) { /* 从中线向右扫描 */
        RightBorderSum += nums[i];
        if( RightBorderSum > MaxRightBorderSum )
            MaxRightBorderSum = RightBorderSum;
    } /* 右边扫描结束 */

    /* 下面返回"治"的结果 */
    return getmaxint3( MaxLeftSum, MaxRightSum, MaxLeftBorderSum + MaxRightBorderSum );
}

//思路三,分而治之,先分后治,采用递归的思想
//时间复杂度为T(n)=O(nlogn)
int maxsubseqsum3(int nums[],int size) {
    return dividegovern(nums,0,size-1);
}

//思路四,在线处理
//时间复杂度T(n) =O(n)
int maxsubseqsum4(int nums[],int size) {
    int i,j,k;
    int sum,thissum;
    sum=0;
    //子列的左边 0.....size-1
    for(i=0; i<size; i++) {
        //子列的右边 i....size-1
        for(j=i; j<size; j++) {
            thissum=0;
            //循环累加求和i...j
            for(k=i; k<=j; k++) {
                thissum+=nums[k];
            }
            if(thissum>sum) {
                sum=thissum;
            }
        }

    }
    return sum;
}

最大子列和求解

原文:https://www.cnblogs.com/ericling/p/11773903.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!