个人主页 : zxctscl 如有转载请先通知
一、题目解析: 求子数组最大和,可能会有所有元素和和子数组所有的和比较,然后取最大的一个。
二、算法原理:
class Solution {
public:
int maxSubArray(vector<int>& nums) {
int n=nums.size();
vector<int> dp(n+1);
dp[0]=0;
int ret=INT_MIN;
for(int i=1;i<=n;i++)
{
dp[i]=max(nums[i-1],dp[i-1]+nums[i-1]);
ret=max(ret,dp[i]);
}
return ret;
}
};
一、题目解析: 这个题与上面一个类似,就是变成了环形。那么这里就可以分为两类:一类是中间相连子数组求最大和;另一类是在结尾和开头求最大和,这里会不方便计算,那么就过来,求中间连续子数组最小和,然后用这个数组的和减去这个最小和,就是这段首尾的最大和。然后比较这两类的和大小,返回最大的那个值就可以了。
二、算法原理:
那么g[i]也可能分两种情况:一种就是只有一个数,就是i对应的nums[i];另一种情况就是不止一个数就是i-1最小的子数组和g[i-1]加上i位置对应的nums[i]。然后取这两种情况的最小值。 f[i]:状态转移方程:g[i]=min(nums[i],g[i-1]+nums[i])
class Solution {
public:
int maxSubarraySumCircular(vector<int>& nums) {
int n = nums.size();
vector<int> f(n+1),g(n+1);
int fmax=INT_MIN,sum=0,gmin=INT_MAX;
for(int i=1;i<=n;i++)
{
f[i]=max(nums[i-1],f[i-1]+nums[i-1]);
fmax=max(fmax,f[i]);
g[i]=min(nums[i-1],g[i-1]+nums[i-1]);
gmin=min(gmin,g[i]);
sum+=nums[i-1];
}
return sum==gmin?fmax:max(fmax,sum-gmin);
}
};
一、题目解析: 求子数组最大乘积,可能会有所有元素和和子数组所有的和比较,然后取最大的一个。但是可能会存在i位置小于0,所以的多加一个数组。
二、算法原理:
g[i]就可能分两种情况:一种就是只有一个数,就是i对应的nums[i];另一种情况就是不止一个数就是i-1最小的子数组乘积f[i-1]乘i位置对应的nums[i],但是这里的nums[i]可能是小于0,所以这里还得分两种情况:一个是nums[i]>0,那么就是最小的子数组乘积g[i-1]乘i位置对应的nums[i];如果nums[i]<0,就是最大的子数组乘积g[i-1]乘i位置对应的nums[i]。然后取这两种情况的最小值。
class Solution {
public:
int maxProduct(vector<int>& nums) {
int n = nums.size();
vector<int> f(n+1),g(n+1);
f[0]=g[0]=1;
int ret=INT_MIN;
for(int i=1;i<=n;i++)
{
int x=nums[i-1],y=f[i-1]*nums[i-1],z=g[i-1]*nums[i-1];
f[i]=max(x,max(y,z));
g[i]=min(x,min(y,z));
ret=max(ret,f[i]);
}
return ret;
}
};
一、题目解析: 求数组乘积为正数的最长长度,可能会有所有元素和和子数组所有的和比较,然后取最大的一个。但是可能会存在i位置小于0,所以的多加一个数组。 二、算法原理:
再把这两种情况优化一下,当num[i]>0,那么如果只有num[i]结果就是1,也就是没有不止一个元素的时候大,所以,直接用f[i-1]+1就行。 num[i]<0,先判断判断g[i-1]是否等于0,是就是0,不是就取g[i-1]+1。 f的状态转移方程:
那么g[i]就可能分两种情况:一种就是只有一个数,就是i对应的nums[i],如果num[i]<0,长度就为1,num[i]>0,长度就为0; 另一种情况就是不止一个数就是i-1最大的子数组乘积为负数的最长长度,如果num[i]>0,长度就为就是以i-1为结尾的子数组乘积为负数的最长长度再加1,也不能直接加一,先判断判断g[i-1]是否等于0,是就是0,不是就取g[i-1]+1; num[i]<0,长度就为就是以i-1为结尾的子数组乘积为正数的最长长度再加1。
g的状态转移方程:
class Solution {
public:
int getMaxLen(vector<int>& nums) {
int n = nums.size();
vector<int> f(n+1),g(n+1);
int ret=INT_MIN;
for(int i=1;i<=n;i++)
{
if(nums[i-1]>0)
{
f[i]=f[i-1]+1;
g[i]=g[i-1]==0?0:g[i-1]+1;
}
else if(nums[i-1]<0)
{
f[i]=g[i-1]==0?0:g[i-1]+1;
g[i]=f[i-1]+1;
}
ret=max(ret,f[i]);
}
return ret;
}
};
有问题请指出,大家有一起进步!!!