思路一:
动态规划O(n), 用一个变量记录当前和, 全局最大值不停地和其进行比较更新, 如果当前和小于0了, 就置0, 不要之前拖后腿的值了.
思路二:
分治法(O(nlogn)), 典型分治, 一个数组的最大子数组和就是从中间劈两半, 左边子数组的最大子数组和&右边子数组的最大子数组和&中间跨左右两个子数组的子数组的最大子数组和这三个数的最大值. 用递归完成即可. 建议都掌握.
int maxSubArray(vector<int>& nums) {
if (nums.empty()) return 0;
int maxSum = INT_MIN, curSum = 0;
for (int i = 0; i < nums.size(); i++) {
curSum += nums[i];
maxSum = max(maxSum, curSum);
if (curSum < 0) curSum = 0;
}
return maxSum;
}
void divideAndConquer(int& res, vector<int>& nums, int left, int right) {
if (left > right) return;
int mid = (left + right) >> 1;
int leftMax = INT_MIN, rightMax = INT_MIN, curSum = 0;
for (int i = mid - 1; i >= left; i--) {
curSum += nums[i];
leftMax = max(leftMax, curSum);
}
curSum = 0;
for (int i = mid + 1; i <= right; i++) {
curSum += nums[i];
rightMax = max(rightMax, curSum);
}
res = max(leftMax + nums[mid] + rightMax, res);
divideAndConquer(res, nums, left, mid - 1);
divideAndConquer(res, nums, mid + 1, right);
}
int maxSubArray(vector<int>& nums) {
if (nums.empty()) return 0;
int left = 0, right = nums.size() - 1;
int res = INT_MIN;
divideAndConquer(res, nums, left, right);
return res;
}