连续子数组的最大和【剑指Offer】
连续子数组的最大和
输入一个 非空 整型数组,数组里的数可能为正,也可能为负。
数组中一个或连续的多个整数组成一个子数组。
求所有子数组的和的最大值。
要求时间复杂度为 O(n)。
数据范围
数组长度 [1,1000]。
数组内元素取值范围 [−200,200]。
样例
输入:[1, -2, 3, 10, -4, 7, 2, -5]
输出:18
思路1贪心
贪心策略:
- 如果和要变小,那么先取一遍max
- 如果临时和t小于0(此时前面的方案已经不可取,对最大和的贡献是负的)那么将t清0
代码1
点击查看代码
class Solution {
public:
int maxSubArray(vector<int>& nums) {
bool f = 0;
int maxn = -300;
for(int i = 0; i < nums.size(); i ++ ){
if(nums[i] >= 0)f = 1;
maxn = max(maxn,nums[i]);
}
int t = 0;
int ans = 0;
if(f){
for(int i = 0; i < nums.size(); i ++ ){
if(nums[i] < 0)ans = max(ans,t);
t += nums[i];
if(t < 0)t = 0;
}
ans = max(ans,t);
return ans;
}
else{
return maxn;
.//如果全部都是负数,那么最大得到数即为最大和
}
}
};
思路2dp
定义
状态转移方程为
代码2
点击查看代码
class Solution {
public:
int maxSubArray(vector<int>& nums) {
int dp[nums.size()];
dp[0] = nums[0];
int ans = nums[0];
for(int i = 1; i < nums.size(); i ++ ){
dp[i] = max(dp[i - 1] + nums[i], nums[i]);
ans = max(dp[i],ans);
}
return ans;
}
};
代码3滚动数组优化
由于dp数组只用到了i-1,因此可以考虑用滚动数组进行优化
点击查看代码
class Solution {
public:
int maxSubArray(vector<int>& nums) {
int a = nums[0],ans = nums[0];
for(auto x:nums){
a = max(a + x, x);
ans = max(a,ans);
}
return ans;
}
};
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!