最大子序列和,最小子序列和,最小正子序列和,最大子序列乘积

来自:【数据结构与算法分析——C语言描述】练习2.12

有关这 4 个子序列算法的思路,都是源于 最大子序列和问题 的延伸,具体请参考 【数据结构与算法分析——C语言描述】第二章总结 算法分析 中的 “最大子序列和问题”部分。

下面是 4 个子序列算法的代码实现。

 

最大子序列和

1. 穷举法,时间复杂度O(N3

int maxSequenceSum1(const int A[], int N)
{
    int i, j, k, maxSum, thisSum;

    maxSum = 0;
    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;
}

2. 撤一个for,O(N2

int maxSequenceSum2(const int A[], int N)
{
    int i, j, maxSum, thisSum;

    maxSum = 0;
    for (i = 0; i < N; i++)
    {
        thisSum = 0;
        for (j = i; j < N; j++)
        {
            thisSum += A[j];

            if (thisSum > maxSum)
                maxSum = thisSum;
        }
    }
    return maxSum;
}

 3. 分治算法,O(NlogN)

int maxSubSum(const int A[], int left, int right)
{
    int maxLeftSum, maxRightSum;
    int maxLeftBorderSum, maxRightBorderSum;
    int leftBorderSum, rightBorderSum;
    int center, i;

    if (left == right)    /*Base case*/
    {
        if (A[left] > 0)
            return A[left];
        else
            return 0;
    }

    center = (left + right) / 2;
    maxLeftSum = maxSubSum(A, left, center);
    maxRightSum = maxSubSum(A, center + 1, right);

    maxLeftBorderSum = 0;    leftBorderSum = 0;
    for (i = center; i >= left; i--)
    {
        leftBorderSum += A[i];
        if (leftBorderSum > maxLeftBorderSum)
            maxLeftBorderSum = leftBorderSum;
    }

    maxRightBorderSum = 0;    rightBorderSum = 0;
    for (i = center + 1; i <= right; i++)
    {
        rightBorderSum += A[i];
        if (rightBorderSum > maxRightBorderSum)
            maxRightBorderSum = rightBorderSum;
    }
    return max(maxLeftSum, maxRightSum,
        maxLeftBorderSum + maxRightBorderSum);
}

int maxSequenceSum3(const int A[], int N)
{
    return maxSubSum(A, 0, N - 1);
}

 4. 联机算法,O(N)

int maxSequenceSum4(const int A[], int N)
{
    int i, maxSum, thisSum;

    maxSum = 0; thisSum = 0;
    for (i = 0; i < N; i++)
    {
        thisSum += A[i];

        if (thisSum> maxSum)
            maxSum = thisSum;
        else if (thisSum < 0)
            thisSum = 0;
    }
    return maxSum;
}

 

 下面,我仍然采用更优的联机算法来求解最小子序列和最小正子序列和、以及最大子序列乘积

 

最小子序列和

int minSequenceSum(const int A[],int N)
{
    int minSum, thisSum, i;

    minSum = 0; thisSum = 0;
    for (i = 0; i < N; i++)
    {
        thisSum += A[i];;

        if (thisSum < minSum)
            minSum = thisSum;
        else if (thisSum>0)
            thisSum = 0;
    }
    return minSum;
}

 

最小正子序列和

int minPositiveSubSum(const int A[], int N)
{
    int minSum, thisSum, i;

    minSum = 0x7FFFFFFF; thisSum = 0;
    for (i = 0; i < N; i++)
    {
        thisSum += A[i];

        if (thisSum < minSum && thisSum > 0)
            minSum = thisSum;
        else if (thisSum < 0)
            thisSum = 0;
    }
    return minSum;
}

 

最大子序列乘积

int maxPositiveSubMul(const int A[], int N)
{
    int maxMul, thisMul, i;

    maxMul = 1; thisMul = 1;
    for (i = 0; i < N; i++)
    {
        thisMul *= A[i];

        if (thisMul > maxMul)
            maxMul = thisMul;
    }

    return maxMul;
}

 

posted @ 2016-09-24 22:14  mingc  阅读(2308)  评论(1编辑  收藏  举报