概述
描述
输入一个长度为n的整型数组array,数组中的一个或连续多个整数组成一个子数组,子数组最小长度为1。求所有子数组的和的最大值。
数据范围:
1 <= n <= 2×105
−100 <= a[i] <= 100
要求:时间复杂度为 O(n),空间复杂度为 O(n)
进阶:时间复杂度为 O(n),空间复杂度为 O(1)
示例1
输入:[1,-2,3,10,-4,7,2,-5]
返回值:18
说明:经分析可知,输入数组的子数组[3,10,-4,7,2]可以求得最大和为18
示例2
输入:[2]
返回值:2
示例3
输入:[-10]
返回值:-10
方法一:动态规划 状态定义:
dp[i]表示以i结尾的连续子数组的最大和。所以最终要求dp[n-1] 状态转移方程:dp[i] = max(array[i], dp[i-1]+array[i]) 解释:如果当前元素为整数,并且dp[i-1]为负数,那么当然结果就是只选当前元素 技巧:这里为了统一代码的书写,定义dp[i]表示前i个元素的连续子数组的最大和,结尾元素为array[i-1]
class Solution {
public:
int FindGreatestSumOfSubArray(vector<int> array) {
//记录到下标i为止的最大连续子数组和 fast-template
vector<int> dp(array.size(), 0);
dp[0] = array[0];
int maxsum = dp[0];
for (int i = 1; i < array.size(); i++) {
//状态转移:连续子数组和最大值
dp[i] = max(dp[i - 1] + array[i], array[i]);
//维护最大值
maxsum = max(maxsum, dp[i]);
}
return maxsum;
}
};
运行时间:34ms
超过3.04% 用C++提交的代码
占用内存:5740KB
超过14.05%用C++提交的代码
时间复杂度:O(n) 空间复杂度:O(n)
方法二:空间复杂度O(1)解法
思想很简单,就是对下标为i的元素array[i],先试探的加上array[i], 如果和为负数,显然,以i结尾的元素对整个结果不作贡献。 具体过程:
- 初始化:维护一个变量tmp = 0
- 如果tmp+array[i] < 0, 说明以i结尾的不作贡献,重新赋值tmp = 0
- 否则更新tmp = tmp + array[i] 最后判断tmp是否等于0, 如果等于0, 说明数组都是负数,选取一个最大值为答案。
代码 :
class Solution {
public:
int FindGreatestSumOfSubArray(vector<int> array) {
int ret = 0;
int tmp = 0;
for (const int k : array) {
if (tmp + k < 0) {
tmp = 0;
}
else {
tmp += k;
}
ret = max(ret, tmp);
}
if (ret != 0)
return ret;
return *max_element(array.begin(), array.end());
}
};
运行时间:32ms
超过4.34% 用C++提交的代码
占用内存:5692KB
超过15.83%用C++提交的代码
时间复杂度:O(n) 空间复杂度:O(1)
最后
以上就是繁荣星月为你收集整理的【JZ42 连续子数组的最大和】的全部内容,希望文章能够帮你解决【JZ42 连续子数组的最大和】所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复