1186. 删除一次得到子数组最大和
思路:假设枚举子数组的左右端点,那么时间复杂度为0(n^2),超时。
枚举子数组的右端点,左端点通过动态规划来找到,时间复杂度为0(n)。
状态dp[i][0]:表示右端点为i,且删掉的元素个数为0时,子数组的区间和
状态dp[i][1]:表示右端点为i,且删掉的元素个数为1时,子数组的区间和
class Solution {
public:
int maximumSum(vector<int>& arr) {
int n=arr.size();
vector<vector<int>> dp(n+1,vector<int>(2));
//初始化
dp[0][1]=0;
dp[0][0]=arr[0];
//记录子数组的最大值
int res=arr[0];
for(int i=1;i<n;i++){
dp[i][0]=max(0,dp[i-1][0])+arr[i];
dp[i][1]=max(dp[i-1][1]+arr[i],dp[i-1][0]);
res=max(res,max(dp[i][0],dp[i][1]));
}
return res;
}
};
状态转移只用到了前面的一个状态,可以优化一下空间
class Solution {
public:
int maximumSum(vector<int>& arr) {
int n=arr.size();
int f1=0;
int f0=arr[0];
int res=arr[0];
for(int i=1;i<n;i++){
f1=max(f1+arr[i],f0);
f0=max(0,f0)+arr[i];
res=max(res,max(f0,f1));
}
return res;
}
};