题目链接:https://leetcode-cn.com/problems/maximum-length-of-subarray-with-positive-product/
题意:
给你一个整数数组 nums ,请你求出乘积为正数的最长子数组的长度。
一个数组的子数组是由原数组中零个或者更多个连续数字组成的数组。
请你返回乘积为正数的最长子数组长度。
方法:动态规划,定义dp数组,存储前i个数字里,乘积为正数的最长子数组
class Solution {
public:
int getMaxLen(vector<int>& nums) {
int size = nums.size();//记录子数组长度
int maxL = 0;//统计最大长度
vector<vector<int>> dp(size, vector<int>(2));//动态规划数组,dp[i][0]表示前i个数乘积为正数的最大长度,dp[i][1]表示前i个数乘积为负数的最大长度
if (nums[0] > 0)//定义首个节点dp的状态,如果第一个数大于0
{
dp[0][0] = 1;//乘积为正数,长度置为1
dp[0][1] = 0;//长度置为0
maxL = 1;
}
else if (nums[0] < 0)//如果第一个数小于0
{
dp[0][0] = 0;//乘积为负数,长度置为0
dp[0][1] = 1;//长度置为1
}
for (int i = 1; i < size; i++)
{
if (nums[i - 1] == 0)//如果前一个数是0,更新当前dp
{
if (nums[i] > 0)
{
dp[i][0] = 1;//长度置为1
dp[i][1] = 0;//长度置为0
maxL = max(maxL, dp[i][0]);//更新最大长度
}
else if (nums[i] < 0)
{
dp[i][0] = 0;//长度置为0
dp[i][1] = 1;//长度置为1
}
}
else
{
if (nums[i] > 0)//如果当前的数为正数
{
dp[i][0] = 1;//先定义一下dp的初始状态,因为至少可以从该位开始状态变换
dp[i][1] = 0;
if (dp[i - 1][0] > 0)//如果之前的乘积大于0的情况存在
{
dp[i][0] = dp[i - 1][0] + 1;//乘积为正的长度累加
maxL = max(maxL, dp[i][0]);//更新最大长度
}
if (dp[i - 1][1] > 0)//如果之前的乘积小于0的情况存在,重新更新一下乘积为负的情况
{
dp[i][1] = dp[i - 1][1] + 1;//乘积为负的长度累加
maxL = max(maxL, dp[i][0]);//更新最大长度
}
}
else if (nums[i] < 0)//如果当前的数为负数
{
dp[i][0] = 0;//先定义一下dp的初始状态,因为至少可以从该位开始状态变换
dp[i][1] = 1;
if (dp[i - 1][0] > 0)//如果之前的乘积大于0的情况存在
{
dp[i][1] = dp[i - 1][0] + 1;//乘积为负的长度累加
}
if (dp[i - 1][1] > 0)//如果之前的乘积小于0的情况存在
{
dp[i][0] = dp[i - 1][1] + 1;//乘积为正的长度累加
maxL = max(maxL, dp[i][0]);//更新最大长度
}
}
}
}
return maxL;//返回最大长度
}
};
优化后:
class Solution {
public:
int getMaxLen(vector<int>& nums) {
int size = nums.size();//存储数组长度
int post = nums[0] > 0 ;//乘积为正数的子数组长度
int negt = nums[0] < 0 ;//乘积为负数的子数组长度
int maxL = post;//最大长度
for (int i = 1; i < size; i++)
{
if (nums[i] > 0)//如果当前数大于0
{
post++;//乘积为正数的自加
negt = negt > 0 ? negt + 1 : 0;//更新乘积为负数的子数组长度
}
else if (nums[i] < 0)//如果当前数小于0
{
int nnegt = post + 1;//暂存负的最长子数组长度
int npost = negt > 0 ? negt + 1 : 0;//暂存正的最长子数组长度
post = npost;//更新乘积为正数的子数组长度
negt = nnegt;//更新乘积为负数的子数组长度
}
else//如果当前的数是0
{
post = 0;//更新为全0
negt = 0;
}
maxL = max(maxL, post);//更新最大长度
}
return maxL;//返回最大长度
}
};