数据结构 PAT 01-复杂度1 最大子列和问题

来源:互联网 发布:java调用nodejs程序 编辑:程序博客网 时间:2024/05/29 19:05

01-复杂度1 最大子列和问题

给定K个整数组成的序列{ N1N2, ..., NK },“连续子列”被定义为{ NiNi+1, ..., Nj },其中 1ijK。“最大子列和”则被定义为所有连续子列元素的和中最大者。例如给定序列{ -2, 11, -4, 13, -5, -2 },其连续子列{ 11, -4, 13 }有最大的和20。现要求你编写程序,计算给定整数序列的最大子列和。

输入格式:

输入第1行给出正整数K (100000);第2行给出K个整数,其间以空格分隔。

输出格式:

在一行中输出最大子列和。如果序列中所有整数皆为负数,则输出0。

输入样例:

6-2 11 -4 13 -5 -2

输出样例:

20

#include <stdio.h>// 三个整数的最大值int Max3(int a, int b, int c){    return a>b ? (a>c ? a:c):(b>c ? b:c);}/* 分治法求List[left]到List[right]的最大子列和 */int DivideAndConquer( int List[], int left, int right ){    int maxLeftSum, maxRightSum; // 存放左右子问题的解    int maxLeftBorderSum, maxRightBorderSum; // 存放跨分界线的解    int thisLeftBorderSum, thisRightBorderSum; // 当前跨分界线的解    int center;    // 递归的出口    if (left == right) /* 递归的终止条件,子列只有1个数字 */    {        if (List[left] > 0)            return List[left];        else            return 0;    }    // 下面是分的过程    center = (left + right) / 2; // 找到中分点    // 递归求两边子列的最大和    maxLeftSum = DivideAndConquer(List, left, center);    maxRightSum = DivideAndConquer(List, center+1, right);        /* 下面求跨分界线的最大子列和 */    // 从中分点往左扫描    thisLeftBorderSum = 0, maxLeftBorderSum = 0;    for (int i = center; i>=left; i--)    {        thisLeftBorderSum += List[i];        if (thisLeftBorderSum > maxLeftBorderSum)            maxLeftBorderSum = thisLeftBorderSum;    } // 左边扫描结束        // 从中分点往左扫描    thisRightBorderSum = 0, maxRightBorderSum = 0;    for (int i = center+1; i<=right; i++)    {        thisRightBorderSum += List[i];        if (thisRightBorderSum > maxRightBorderSum)            maxRightBorderSum = thisRightBorderSum;    } // 左边扫描结束    // 下面返回"治"的结果    return Max3(maxLeftSum, maxRightSum, maxLeftBorderSum + maxRightBorderSum);}// 1,分治法,NLogN的时间复杂度int MaxSubseqSum1(int a[], int n){    return DivideAndConquer(a, 0, n-1);}// 2,循环,N平方的时间复杂度int MaxSubseqSum2(int a[], int n){    int thisSum, maxSum = 0;    for (int i = 0; i < n; i++)    {        thisSum = 0;        for (int j = i; j<n; j++)        {            thisSum += a[j];            if (thisSum>maxSum)                maxSum = thisSum;        }    }    return maxSum;}// 3. 在线处理,N的时间复杂度int MaxSubseqSum3(int a[], int n){    int thisSum, maxSum;    thisSum = 0, maxSum = 0;    for (int i = 0; i < n; i++)    {        thisSum += a[i]; // 向右累加        if (thisSum > maxSum)            maxSum = thisSum; // 发现更大和则更新当前结果        else if(thisSum < 0) // 如果当前子列和为负            thisSum = 0; // 置为0,重新向右累加    }    return maxSum;}int main(){    int K;    scanf("%d", &K);    int A[K];    for (int i = 0; i<K; i++)        scanf("%d", &A[i]);    printf("%d\n", MaxSubseqSum3(A,K));    return 0;}


0 0