终于要开始学习算法了,想想都有点激动,理论的东西稍后再说,先来个例子看看
一、问题描述
给定n个整数(可能为负数)组成的序列a[1],a[2],a[3],…,a[n],求该序列如a[i]+a[i+1]+…+a[j]的子段和的最大值。当所给的整均为负数时定义子段和为0,依此定义,所求的最优值为: Max{0,a[i]+a[i+1]+…+a[j]},1<=i<=j<=n。
输入:
一个数组,由n个整数组成
输出:
这个数组的最大子段和
二、例子分析
一个数组{3,-5,6,2},它的最大子段和为8。
分析:
首先咱们只是单纯的分析下这个问题,数组中有4个元素,这个数组所有的子段和如下
从图中可以看出,要想求出最大子段和,只要按照数组中元素的先后顺序,把所有相邻元素的相加情况列出来,通过比较相加的结果就可以得到最大子段和。思路如下:
第一步:计算所有关于第1个元素的加法
第二步:计算所有关于第2个元素的加法(排除第一步中用到的加法)
第三步:计算所有关于第3个元素的加法(排除第一、二步中用到的加法)
……
第五步:比较以上步骤中所有加法的结果大小,最大者即为所求
三、程序
当数组中元素增多时,显然用手动的方式来计算就太费劲了,所以把上边解题的思路编成程序,让计算机来帮我们进行运算。
/// <summary>
/// 最大子段和问题:求最大值
/// </summary>
/// <param name="a">一个长度为n的二维数组</param>
/// <param name="n">二维数组的长度</param>
/// <returns></returns>
int Max(int[] a, int n)
{
int max = 0;
int temp = 0;
//循环数组中所有的元素
for (int i = 0; i < n; i++)
{
//包含第j个元素的所有相加情况,并去掉已经加过的情况
for (int j = i; j < n; j++)
{
temp += temp + a[j];//把相加的结果,放到一个变量中
//比较相加的结果是否比已有的最大值大
if (max < temp)
{
max = temp; //替换最大值
}
}
}
return max; //返回最大值
}
这个是求最大子段和的最基础思路,很简单,就是嵌套了两个for循环、一个if语句不太好。它还有很多种优化思路,亲们自行解决吧