给你一个整数数组 nums,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
子数组 是数组中的一个连续部分。
示例 1:
输入:nums = [-2,1,-3,4,-1,2,1,-5,4]
输出:6
解释:连续子数组 [4,-1,2,1] 的和最大,为 6。
示例 2:
输入:nums = [1]
输出:1
示例 3:
输入:nums = [5,4,-1,7,8]
输出:23
提示:
1 <= nums.length <= 10^5
-10^4 <= nums[i] <= 10^4
进阶:如果你已经实现复杂度为 O(n) 的解法,尝试使用更为精妙的 分治法 求解。
#include
int maxSubArray(int* nums, int numsSize) {
int sum = 0;
int maxSum = nums[0];
bool haveMoreThan0 = false;
for (int i = 0; i < numsSize; i++)
{
if(nums[i] < 0)
{
if(haveMoreThan0)
{
continue;
}
}
else
{
haveMoreThan0 = true;
}
sum = 0;
for (int j = i; j < numsSize; j++)
{
sum += nums[j];
maxSum = maxSum < sum ? sum : maxSum;
}
}
return maxSum;
}
这套代码用了暴力法。
通过嵌套的两层循环,遍历所有可能的子数组并计算它们的和,记录其中的最大和。外层循环确定子数组的起始位置,内层循环计算从该起始位置到数组末尾的所有子数组的和。
maxSubArray函数int maxSubArray(int* nums, int numsSize) {
int sum = 0;
int maxSum = nums[0];
bool haveMoreThan0 = false;
for (int i = 0; i < numsSize; i++)
{
if(nums[i] < 0)
{
if(haveMoreThan0)
{
continue;
}
}
else
{
haveMoreThan0 = true;
}
sum = 0;
for (int j = i; j < numsSize; j++)
{
sum += nums[j];
maxSum = maxSum < sum ? sum : maxSum;
}
}
return maxSum;
}
maxSubArray函数的解析:
sum变量用于计算当前子数组的和。maxSum变量用于记录当前最大子数组和。haveMoreThan0变量用于判断是否有正数存在,若存在则跳过负数子数组。O(n^2)。O(1)。int maxSubArray(int* nums, int numsSize) {
int currentSum = nums[0];
int maxSum = nums[0];
for (int i = 1; i < numsSize; i++) {
currentSum = (currentSum > 0) ? (currentSum + nums[i]) : nums[i];
maxSum = (maxSum > currentSum) ? maxSum : currentSum;
}
return maxSum;
}
这套代码用了动态规划方法。
通过遍历数组,动态更新当前子数组的最大和。如果当前子数组的和小于0,则从当前元素重新开始计算子数组和,否则继续累加当前元素。记录遍历过程中遇到的最大子数组和。
maxSubArray函数int maxSubArray(int* nums, int numsSize) {
int currentSum = nums[0];
int maxSum = nums[0];
for (int i = 1; i < numsSize; i++) {
currentSum = (currentSum > 0) ? (currentSum + nums[i]) : nums[i];
maxSum = (maxSum > currentSum) ? maxSum : currentSum;
}
return maxSum;
}
maxSubArray函数的解析:
currentSum变量用于记录当前子数组的和。maxSum变量用于记录最大子数组的和。O(n)。O(1)。int maxCrossingSum(int* nums, int left, int mid, int right) {
int sum = 0;
int leftSum = INT_MIN;
for (int i = mid; i >= left; i--) {
sum += nums[i];
if (sum > leftSum) {
leftSum = sum;
}
}
sum = 0;
int rightSum = INT_MIN;
for (int i = mid + 1; i <= right; i++) {
sum += nums[i];
if (sum > rightSum) {
rightSum = sum;
}
}
return leftSum + rightSum;
}
int maxSubArraySum(int* nums, int left, int right) {
if (left == right) {
return nums[left];
}
int mid = (left + right) / 2;
int leftMax = maxSubArraySum(nums, left, mid);
int rightMax = maxSubArraySum(nums, mid + 1, right);
int crossMax = maxCrossingSum(nums, left, mid, right);
return (leftMax > rightMax) ? ((leftMax > crossMax) ? leftMax : crossMax) : ((rightMax > crossMax) ? rightMax : crossMax);
}
int maxSubArray(int* nums, int numsSize) {
return maxSubArraySum(nums, 0, numsSize - 1);
}
这套代码用了分治法方法。
通过分治法,将数组分为两部分,递归地求解左半部分、右半部分和跨中间部分的最大子数组和。最后返回这三部分中的最大值。
maxCrossingSum函数int maxCrossingSum(int* nums, int left, int mid, int right) {
int sum = 0;
int leftSum = INT_MIN;
for (int i = mid; i >= left; i--) {
sum += nums[i];
if (sum > leftSum) {
leftSum = sum;
}
}
sum = 0;
int rightSum = INT_MIN;
for (int i = mid + 1; i <= right; i++) {
sum += nums[i];
if (sum > rightSum) {
rightSum = sum;
}
}
return leftSum + rightSum;
}
maxCrossingSum函数的解析:
maxSubArraySum函数int maxSubArraySum(int* nums, int left, int right) {
if (left == right) {
return nums[left];
}
int mid = (left + right) / 2;
int leftMax = maxSubArraySum(nums, left, mid);
int rightMax = maxSubArraySum(nums, mid + 1, right);
int crossMax = maxCrossingSum(nums, left, mid, right);
return (leftMax > rightMax) ? ((leftMax > crossMax) ? leftMax : crossMax) : ((rightMax > crossMax) ? rightMax : crossMax);
}
maxSubArraySum函数的解析:
maxSubArray函数int maxSubArray(int* nums, int numsSize) {
return maxSubArraySum(nums, 0, numsSize - 1);
}
maxSubArray
函数的解析:
maxSubArraySum函数,传入整个数组的范围(0到numsSize - 1),返回最大子数组和。O(n log n)。log n,空间复杂度为 O(log n)。

