Leetcode:Maximum Subarray

Maximum Subarray

题目链接:https://oj.leetcode.com/problems/maximum-subarray/
runtimes:12ms

一、问题

        Find the contiguous subarray within an array (containing at least one number) which has the largest sum. For example, given the array [−2,1,−3,4,−1,2,1,−5,4], the contiguous subarray [4,−1,2,1] has the largest sum = 6.

二、分析

        找出序列[−2,1,−3,4,−1,2,1,−5,4]中和最大的子序列,按照传统的思维,需要枚举每一个以i元素为首的子序列,求得所有和之后比较选择最大的和的那个序列,这样需要O(n^2)的时间,显然不符合题目的要求。那么一定要在O(n)内找出答案,就只能遍历一次。想了很久没有想明白其中的所以然,于是乎找人讨论,给了一个小于零的和无效的想法,即前面N-1个数的和如果不超过零,那么对Nth数的和没意义,就舍去前N-1个数的和,从Nth开始计算和。想想觉得挺有道理,但是要证明还是有一定难度。(证明:既然前N-1个数的和加上去使得比A[i]还要小,那么就没必要加上,直接从A[i]开始累积反而起点更高。假如前N-1个数的和为S1,且S1 + A[N] < A[N],即S1 < 0,此时有包含Nth数的最大和子序列,其和为S2,假设存在包含Nth数的另外一个和最大子序列,同时包含了N-1个数,那么有S1 + A[n] + S2 - A[n] > A[n] + S2 - A[n],即S1 > 0,与原题设不符,因此不存在酱紫的序列。)

三、总结

        1、枚举每一个以i元素为首的子序列,其中和最大的子序列即为所求答案。
        2、从头扫描数组,假如扫描到Nth个数,如果N-1个数的和不超过零,那么舍去,重新从Nth个数开始累加;如果大于零,则继续累加。过程中需要记录每次累加的到的和,并保留最大的那个和。
        3、从运行时间分布来看,速度分别是c++ > python > java,C++太高效了,赞!

四、方案

        方案一:
class Solution {
public:
	int maxSubArray(int A[], int n) {
		int maxCount = INT_MIN, temp;
		for (int i = 0; i < n; i++)
		{
			temp = A[i];
			for (int j = i + 1; j < n; j++)
			{
				temp += A[j];
				if (temp > A[i])
				{
					A[i] = temp;
				}
			}
			if (A[i] > maxCount)
				maxCount = A[i];
		}
		return maxCount;
	}
};



        方案二:
class Solution {
public:
	int maxSubArray(int A[], int n) {
		int sum = 0, record = INT_MIN,counter = 0;
		for (int i = 0; i < n; i++)
		{
			if (A[i] <= 0)
			{
				counter++;
			}
			sum += A[i];
			if (sum <= 0)
			{
				sum = 0;
			}
			else{
				record = record < sum ? sum : record;
			}
		}
		if (counter == n)
		{
			record = A[0];
			for (int i = 1; i < n; i++)
			{
				record = record < A[i] ? A[i] : record;
			}
		}
		return record;
	}
};




五、反思

        找到了一篇详细分析的文章,使用了动态规划的思想,扫描数组,每个元素算一个阶段,在阶段中的状态是A[i],决策是选择sum + A[i]和A[i]中最大者作为新阶段的出发点,与前N-1项和无效一样,只不过我是以0为分界点,小于零就舍去,该程序是取较大者,酱紫就省去了排除负数的阶段,赞!状态转移方程是sum = Max(sum + A[i], A[i]),同时要保留在这个过程中的最大和值。用了java,程序的运行时间是235!
        原文链接:http://www.programcreek.com/2013/02/leetcode-maximum-subarray-java/
        另外重新对动态规划思想进行认识,这篇文章的摘要写的挺好:http://www.cnblogs.com/lvpengms/archive/2010/02/03/1663055.html
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值