Maximum Subarray

题目:

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.

click to show more practice.

More practice:

If you have figured out the O(n) solution, try coding another solution using the divide and conquer approach, which is more subtle.

解析:

最大连续子序列和,非常经典的题。
当我们从头到尾遍历这个数组的时候,对于数组里的一个整数,它有几种选择呢?它只有两种
选择:1、加入之前的 SubArray;2. 自己另起一个 SubArray。那什么时候会出现这两种情况呢?
如果之前 SubArray 的总体和大于 0 的话,我们认为其对后续结果是有贡献的。这种情况下我们
选择加入之前的 SubArray
如果之前 SubArray 的总体和为 0 或者小于 0 的话,我们认为其对后续结果是没有贡献,甚至是
有害的(小于 0 时) 。这种情况下我们选择以这个数字开始,另起一个 SubArray。
设状态为 f[j],表示以 S[j] 结尾的最大连续子序列和,则状态转移方程如下:
f[j] = max{f[j − 1] + S[j],S[j]}, 其中1 ≤ j ≤ n
target = max{f[j]}, 其中1 ≤ j ≤ n
解释如下:
• 情况一,S[j] 不独立,与前面的某些数组成一个连续子序列,则最大连续子序列和为
f[j − 1] + S[j]。
• 情况二,S[j] 独立划分成为一段,即连续子序列仅包含一个数 S[j],则最大连续子序列和为
S[j]。
其他思路:
• 思路 2:直接在 i 到 j 之间暴力枚举,复杂度是 O(n 3 )
• 思路 3:处理后枚举,连续子序列的和等于两个前缀和之差,复杂度 O(n 2 )。
• 思路 4:分治法,把序列分为两段,分别求最大连续子序列和,然后归并,复杂度 O(nlogn)
• 思路 5:把思路 2O(n 2 ) 的代码稍作处理,得到 O(n) 的算法
• 思路 6:当成 M=1 的最大 M 子段和

动态规划:

 1 class Solution {
 2 public:
 3     int maxSubArray(vector<int>& nums) {
 4         int result = INT_MIN, f = 0;
 5         for (int i = 0; i < nums.size(); ++i) {
 6             f = max(f + nums[i], nums[i]);
 7             result = max(result, f);
 8         }
 9         return result;
10     }
11 };

 

 

posted on 2015-11-17 09:22  已停更  阅读(225)  评论(0编辑  收藏  举报