给定一个整数数组 nums
,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
示例:
输入: [-2,1,-3,4,-1,2,1,-5,4],
输出: 6
解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。
代码①:O(n)
int maxSubArray(int* nums, int numsSize) {
int max = nums[0];
int sum = 0;
for(int i=0; i<numsSize; i++)
{
if( sum>0 ) //sum>0是出现最大和的条件
sum += nums[i];
else
sum = nums[i]; //排除前面最大和<0的连续子数组,重新开始计算
if( sum>max ) //比较,取最大和
max = sum;
}
return max;
}
代码②:分治策略结合递归思想求最大子序列和
参考自:https://blog.csdn.net/gcvdsvb/article/details/36027747
static int MaxSubSum(const int A[], int Left, int Right)
{
if (Left == Right) /* 递归的基准情形 */
return a[Left];
int Center;
Center = (Left + Right) / 2; /* 求分界点 */
int MaxLeftSum;
MaxLeftSum = MaxSubSum(A, Left, Center); /* 递归,求左半部分子序列的最大子序列和 */
int MaxRightSum;
MaxRightSum = MaxSubSum(A, Center + 1, Right); /* 递归,求右半部分子序列的最大子序列和 */
/* 求横跨左半部分和右半部分的最大子序列和 */
/* 首先是左半部分子序列中包含最后一个元素的最大子序列和 */
int MaxLeftBorderSum = A[Center], LeftBorderSum = A[Center];
for (int i = Center - 1; i >= Left; --i) {
LeftBorderSum += A[i];
if (LeftBorderSum > MaxLeftBorderSum)
MaxLeftBorderSum = LeftBorderSum;
}
/* 接着是右半部分子序列中包含第一个元素的最大子序列和 */
int MaxRightBorderSum = A[Center + 1], RightBorderSum = A[Center + 1];
for (int i = Center + 2; i <= Right; ++i) {
RightBorderSum += A[i];
if (RightBorderSum > MaxRightBorderSum)
MaxRightBorderSum = RightBorderSum;
}
/* Max3 返回左、右半部分子序列的最大子序列和以及横跨左、右半部分的最大子序列和中的最大者 */
return Max3(MaxLeftSum, MaxRightSum,
MaxLeftBorderSum + MaxRightBorderSum);
}
int MaxSubsequenceSum(const int A[], int N) /* 求最大子序列和 */
{
return MaxSubSum(A, 0, N - 1);
}