最大子段和(三)

最大子段和问题

解法三:

算法分析:


对于序列a,设j代表当前序列的终点,i代表当前序列的起点

分析:如果a[i]是负的,那么它不可能是最大子段的起点,因为任何包含a[i]为起点的子段都可以通过
         用a[i+1]为起点而得到改进。类似的,任何负的子段都不可能是最优子段的前缀(原理相同).
         如果在循环中检测到a[i]到a[j]的子段是负的,那么可以推进i.

结论:不仅能把i推进到i+1,而且可以一直推进到j+1.
原因:令p为i+1和j之间的任一下标。开始于下标p的任意子段都不大于从下标i开始并包含从a[i]到a[p-1]的子段,

        因为a[i]到a[p-1]这个子段不是负的(j是使得从下标i开始,其值成为负值序列的第一个下标)

 

算法实现:

public class MaxSum 
{
	public static int maxSubSum(int[] a)
	{
		int maxSum = 0;
		int thisSum = 0;

		for (int j = 0; j < a.length; j++)
		{
			thisSum += a[j];
			if (thisSum > maxSum)
			{
				maxSum = thisSum;
			}
			else if (thisSum < 0)
			{
				thisSum = 0;
			}
		}

		return maxSum;
	}
	public static void main(String[] args) 
	{
		int[] a = {-2, 11, -4, 13, -5, -2};
		System.out.println(MaxSum.maxSubSum(ar));
	}
}

算法的优点:

1)运行时间最短;

2)而且只对数据进行一次扫描,一旦a[i]被读入并被处理,它就不在需要被记忆;

3)在任何时刻,算法都能对已读入的数据给出该问题的正确答案;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值