最大子序列和

最大子序列和的4种算法

给定整数A1,A2…An(可能有负数)求最大子序列和。(假设所有整数均为负数时,最大子序列和为0)

Arg1

public int MaxSubsequenceSum(int arr[], int n) {
    int ThisSum, MaxSum;
    MaxSum = 0;

    for (int i = 0; i < n; i++) {
        for (int j = i; j < n; j++) {
            ThisSum = 0;
            for (int k = i; k <= j; k++)
                ThisSum += arr[k];

            if (ThisSum > MaxSum)
                MaxSum = ThisSum;
        }
    }
    return MaxSum;
}

时间复杂度O(N3)

Arg2

public int MaxSubsequenceSum(int arr[], int n) {
    int ThisSum, MaxSum;
    MaxSum = 0;

    for (int i = 0; i < n; i++) {
        ThisSum = 0;
        for (int j = i; j < n; j++) {

            ThisSum += arr[j];

            if (ThisSum > MaxSum)
                MaxSum = ThisSum;
        }
    }
    return MaxSum;
}

时间复杂度O(N2)

Arg3

分治法的思想,
“分”:将问题分成两个大致相同的子问题,然后递归的解决
“治”:将两个子问题的解合并。

在本例中,最大子序列和可能出现在3处:左半部,右半部,占据左右两个部分。
前两种情况可以递归求解。后一种情况可以通过求出前半部的最大和(包含最后一个元素)以及后半部的最大和(包含第一个元素),然后相加。
如:4,-3,5,-2,-1,2,6,-2。
第一种情况的最大和为6(A1-A3)
第二种情况的最大和为8(A6-A7)
第三种情况的最大和为11(A1-A7)

public int MaxSubsequenceSum(int arr[], int left, int right) {

    int MaxLeftSum, MaxRightSum;
    int MaxLeftBorderSum, MaxRightBorderSum;
    int LeftBorderSum, RightBorderSum;
    int Center, i;

    if (left == right) {
        if (arr[left] > 0)
            return arr[left];
        else
            return 0;
    }

    Center = (left + right) / 2;

    MaxLeftSum = MaxSubsequenceSum(arr, left, Center);
    MaxRightSum = MaxSubsequenceSum(arr, Center + 1, right);

    MaxLeftBorderSum = 0;
    LeftBorderSum = 0;
    MaxRightBorderSum = 0;
    RightBorderSum = 0;

    for (i = Center; i >= left; i--) {
        LeftBorderSum += arr[i];
        if (LeftBorderSum > MaxLeftBorderSum)
            MaxLeftBorderSum = LeftBorderSum;
    }
    for (i = Center + 1; i <= right; i++) {
        RightBorderSum += arr[i];
        if (RightBorderSum > MaxRightBorderSum)
            MaxRightBorderSum = RightBorderSum;
    }

    int max = MaxLeftSum;
    if (MaxRightSum > max)
        max = MaxRightSum;
    if (max < (MaxRightBorderSum + MaxLeftBorderSum))
        max = MaxRightBorderSum + MaxLeftBorderSum;

    return max;
}

时间复杂度O(NlogN).

Arg4

public int MaxSubsequenceSum(int arr[], int n) {

    int ThisSum=0,MaxSum=0;

    for(int j=0;j<n;j++){
        ThisSum+=arr[j];
        if(ThisSum>MaxSum)
            MaxSum=ThisSum;
        else if(ThisSum<0)
            ThisSum=0;
    }

    return MaxSum;
}

时间复杂度:线性时间O(N).

你可能感兴趣的:(最大子序列和)