算法心得(1)**最大子数组**

直接上模板:

/**************
function: 从数组中获得子数组的最大和 
param: A(数组),n(数组长度)
return: nAll(子数组最大和)
***************/
int MaxSum(int *A, int n)
{
    int nStart = A[0];  //记录当前子序列的和
    int nAll = A[0];
    for (int i = 1; i < n; i++)
    {
        if (nStart < 0)//如果当前子序列的和小于0,那么就抛弃前面的子序列
            nStart = 0;
        nStart += A[i];
        if (nStart > nAll)//如果当前子序列的和大于最大子序列的和,那么更新最大子序列的和
            nAll = nStart;
    }
    return nAll;
}

**分析**

这是一个非常基础的小算法,主要思想是使用一个中间量nStart来计算当前子数组的和。其中有点贪心算法的影子,当nStart小于0时,直接将其“抛弃”(置为0),因为就算该子数组的后面有一个大于0的数组B:

毫无疑问的,最终的nAll里肯定包含有B的值,因为它大于0,最大子数组就是要**尽可能“团结”所有大于0的子数组**,而显而易见的,nStart+B<B,所以将nStart抛弃是对后面没有影响的甚至是必须的,符合贪心算法的前提。

也可以稍微改进一下,使得可以把最终的子数组记录下来:

/**************
function: 从数组中获得子数组的最大和,并记录该子数组的位置
param: A(数组),n(数组长度),start(最终的子数组的起始位置),end(最终的子数组的终点)
return: nAll(子数组最大和)
***************/
int MaxSum(int *A, int n, int *start, int *end)
{
    int nStart = A[0]; // 记录当前子序列的和
    int nAll = A[0];
    *start = 0;
    *end = 0;
    for (int i = 1; i < n; i++)
    {
        if (nStart < 0) // 如果当前子序列的和小于0,那么就抛弃前面的子序列
        {
            nStart = 0;
            *start = i;
        }
        nStart += A[i];
        if (nStart > nAll) // 如果当前子序列的和大于最大子序列的和,那么更新最大子序列的和
        {
            nAll = nStart;
            *end = i;
        }
    }
    return nAll;
}

 

posted @ 2025-03-12 10:22  Travic  阅读(32)  评论(0)    收藏  举报