题目
给定一个整数数组 nums
,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
转载链接 https://leetcode-cn.com/problems/maximum-subarray/
输入: [-2,1,-3,4,-1,2,1,-5,4],
输出: 6
解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。
解答
方法一:
思路是这样的,最直接的思路,从第一个数开始,挨个往后加结果比最大值大,就把最大值更新,一直算到最后一个。
然后再依次从后边一个数字开始。是个暴力方法
class Solution {
public:
int maxSubArray(vector<int>& nums) {
if (nums.size() == 1) {
return nums.front();
}
int max = nums[0];
//最大值是全局的量,每次循环不重置
for (int i = 0; i < nums.size(); i++) {
int data = nums[i];
//单个元素也判断一下,避免遗漏一个元素是最大值的情况
if (data > max) {
max = data;
}
for (int j = i + 1; j < nums.size(); j++) {
data += nums[j];
if (data > max) {
max = data;
}
}
}
return max;
}
};
方法二:
假设在数组中的第n个下标满足了最大的子序和,如果我们知道 n之前的n - 1个元素的最大子序和。那么第n个下标的最大子序和
就是 n -1 下标的最大子序和和 + 下标n元素, 再和下标n元素比较得到的最大值。这样的话一直递推,坐标 0 和坐标1的最大子序和是很容易得到,依次往后计算,就可以得到结果了。
这里f(n) 就代表坐标n对应的最大子序和,每一个坐标对应的最大子序和都有了,那么这里边挑出最大的值就是整个数组的最大子序和了。
class Solution {
public:
int maxSubArray(vector<int>& nums) {
if (nums.size() == 1) {
return nums.front();
}
int max_data = nums[0];
int f_max = max_data;
for (int i = 1; i < nums.size(); i++) {
/// 第i个坐标的之前的最大子序和
f_max = max(f_max + nums[i], nums[i]);
max_data = max(f_max, max_data);
}
return max_data;
}
};