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
.
[解题思路]
问题:求解和最大的连续子数组。
求最大值考虑 DP 思路。
将原问题转换为: 第一步,求 n 个分别以 i 结尾的 和最大的连续子数组。 第二步,找出第1步中最大值的便是原问题的解。
假设第一步已求出,第二步只需要一次遍历就得到答案,耗时 O(n).
如何解第一步:求以 i 结尾的和最大的子数组,可以根据以 ( i-1 ) 结尾的和最大子数组来简单计算。
v[i] = max( v[i-1] + nums[i], 0 )
可见,第一步具有最优子结构性质,符合 DP 思路。
考虑到全部为负数的情况,在算法中增加了一个记号 hasPositive 判断是否存在大于等于 0 的元素, 若不存在则返回数组中的值最大值的负数。
下面是代码实现
/**
* 求一维数组的最大值元素的值
*
*/
int maxElement(vector<int>& v){
int max = v[0];
for (int i = 0 ; i < v.size(); i++) {
if (v[i] > max) {
max = v[i];
}
}
return max;
}
int maxSubArray(vector<int>& nums) {
bool hasPositive = false;
vector<int> v(nums.size(), null_symble);
if (nums[0] >= 0 ) {
hasPositive = true;
v[0] = nums[0];
}else{
v[0] = 0;
}
for (int i = 1 ; i < nums.size(); i++) {
if (v[i-1] + nums[i] >= 0) {
hasPositive = true;
v[i] = v[i-1] + nums[i];
}else{
v[i] = 0;
}
}
int res;
if (hasPositive == false) {
res = maxElement(nums);
}else{
res = maxElement(v);
}
return res;
}