关于最大子列和的四种解法

来源:互联网 发布:美帝国主义 知乎 编辑:程序博客网 时间:2024/06/05 02:21

第一种暴力拿到每个子列的和,取出最大值

int methodNO1(int a[],int N){    //时间复杂度O(n^3)    int thissum , maxsum = 0;    int i,j,k;    for(i = 0;i<N;i++){        for(j = i;j < N; j++){            thissum = 0;            for(k = i;k <= j; k++){                thissum+=a[k];            }            if(thissum > maxsum){                maxsum = thissum;            }        }    }    return maxsum;}

第二种,在第一种上优化,利用第二重循环前面已经得到的子列和

int methodNO2(int a[],int N) {    //时间复杂度O(n^2)    int thissum , maxsum = 0;    int i,j,k;    for(i = 0;i<N;i++){        thissum = 0;        for(j = i;j < N; j++){        thissum += a[j];                        if(thissum > maxsum){                maxsum = thissum;            }        }    }    return maxsum;}

第三种,分而治之

  • 整体思想就是最大子列得和要么出现在数组的左边,要么右边,要么左边右边都包括
  • 分:递归的将大数组每次分成左右两个小数组,当分到最后,就剩一个数,是正数就返回,否则返回0,返回的这个数就是左边或者右边的最大值
  • 合:从中间开始向左找到最大值,向右找到最大值,两者相加就是在中间的最大值
  • 返回三者中的最大值
int methodNO3(int a[],int left,int right){    //分而治之    //时间复杂度O(N*Log(N))     int maxleft,maxright;    int leftboder = 0,maxleftboder = 0;    int rightboder = 0,maxrightboder = 0;    int maxboder,i=0;    //当只有一个数时,返回本身或者0;     if(left == right){        if(a[left]>0){            return a[left];        }else{            return 0;        }     }    //将数组分成两半     int mid = (left + right)/2;    //求左边最大和     maxleft = methodNO3(a,left,mid);    //求右边最大和     maxright = methodNO3(a,mid+1,right);    leftboder =0,maxleftboder =0;    //求从中间开始往左最大值     for(i = mid;i >= left; i--){        leftboder += a[i];        if(leftboder > maxleftboder){            maxleftboder = leftboder;        }    }    rightboder=0,maxrightboder;    //求从中间开始右边最大值     for(i = mid+1;i <= right; i++){        rightboder += a[i];        if(rightboder > maxrightboder){            maxrightboder = rightboder;        }    }    //加起来则是中间最大值    maxboder = maxrightboder + maxleftboder;    if(maxboder < maxleft)        maxboder = maxleft;    if(maxboder < maxright)        maxboder = maxright;    //输出(中间,左边,右边)三个数中的最大值     return maxboder;}

在线处理

int methodNO4(int a[],int N){    //在线处理    //时间复杂度O(N)     int thissum = 0,maxsum = 0;    int i;    for(i = 0;i < N ; i++){        thissum += a[i];        if(thissum > maxsum){ // 如果现在值比最大值大,则更新最大值             maxsum = thissum;        }        if(thissum < 0){ //如果现在值是负数,则他不能让后面的连续值增大,             thissum =0; //所以把现在的值抛弃        }    }    return maxsum;}

大概就是这么多吧,各位看官有什么看法或者意见或者不懂欢迎留言!

原创粉丝点击