Leetcode:Maximum Subarray

来源:互联网 发布:今日值得买网站源码 编辑:程序博客网 时间:2024/05/01 18:44

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
原创粉丝点击