算法心得(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;
}

浙公网安备 33010602011771号