【题目描述】
HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学。今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决。但是,如果向量中包含负数,是否应该包含某个负数,并期望旁边的正数会弥补它呢?例如:{6,-3,-2,7,-15,1,2,2},连续子向量的最大和为8(从第0个开始,到第3个为止)。给一个数组,返回它的最大连续子序列的和,你会不会被他忽悠住?(子向量的长度至少是1)
示例1:
输入 | 输出 |
---|---|
[1,-2,3,10,-4,7,2,-5] | 18 |
//意思就是说,对于输入的序列,求出所有连续的子序列的和的最大值,子序列长度大于等于1,小于等于整个数组长度
//最简单的思路想必都能想到,就是全排列然后求max,但这种复杂又费时
【B站解法】
class Solution {
public:
int FindGreatestSumOfSubArray(vector<int> array) {
int res = INT_MIN, s = 0;
//x 10 -11 3 4
//s 10 -1 3 7
//r 10 10 10 10
for(auto x : array)
{
if(s < 0) s = 0;
s += x;
res = max(res, s);
}
return res;
}
};
官方的2解法与上述解法异曲同工
class Solution {
public:
int FindGreatestSumOfSubArray(vector<int> array) {
int ret = array[0];
int tmp = 0;
for (const int k : array) {
if (tmp + k < 0) {
tmp = 0;
}
else {
tmp += k;
}
ret = max(ret, tmp);
}
if (tmp != 0)
return ret;
return *max_element(array.begin(), array.end());
}
};
【官方-动态规划法】
//想法类似,写法不同
class Solution {
public:
int FindGreatestSumOfSubArray(vector<int> array) {
int sz = array.size();
vector<int> dp(sz+1, 1);
dp[0] = 0; // 表示没有元素
int ret = array[0];
for (int i=1; i<=sz; ++i) {
dp[i] = max(array[i-1], dp[i-1]+array[i-1]);
ret = max(ret, dp[i]);
}
return ret;
}
};