https://leetcode-cn.com/problems/maximum-length-of-subarray-with-positive-product
给你一个整数数组 nums ,请你求出乘积为正数的最长子数组的长度。
一个数组的子数组是由原数组中零个或者更多个连续数字组成的数组。
请你返回乘积为正数的最长子数组长度。
思路:
想得到乘积为正数,那么子序列要满足两个条件:
- 没有0
- 负数为偶数个
使用两个数组,dpP记录乘积为正数的最长子序列长度,dpN记录乘积为负数的最长子序列长度。
nums[i]可以为正数、负数或0。
- nums[i] > 0
(1) dpP[i] = dpP[i - 1] + 1
(2) dpN[i] = dpN[i - 1] === 0 ? 0 : dpN[i - 1] + 1 - nums[i] < 0
(1) dpP[i] = dpN[i - 1] === 0 ? 0 : dpN[i - 1] + 1
(2) dpN[i] = dpP[i - 1] + 1 - nums[i] = 0
(1) dpP[i] = 0
(2) dpN[i] = 0
var getMaxLen = function(nums) {
const len = nums.length;
let dpP = new Array(len).fill(0);
let dpN = new Array(len).fill(0);
if(nums[0] > 0) {
dpP[0] = 1;
} else if(nums[0] < 0) {
dpN[0] = 1;
}
let result = dpP[0];
for (let i = 1; i < len; i++) {
if(nums[i] > 0) {
dpP[i] = dpP[i - 1] + 1;
dpN[i] = dpN[i - 1] === 0 ? 0 : dpN[i - 1] + 1;
} else if (nums[i] < 0) {
dpP[i] = dpN[i - 1] === 0 ? 0 : dpN[i - 1] + 1;
dpN[i] = dpP[i - 1] + 1;
} else {
dpP[i] = 0;
dpN[i] = 0;
}
result = Math.max(result, dpP[i])
}
return result
};
综上所述,可以对dpP和dpN进行状态压缩,设置pos和neg两个变量来不断替换。
var getMaxLen = function(nums) {
const len = nums.length;
let pos = 0;
let neg = 0
if(nums[0] > 0) {
pos = 1;
} else if(nums[0] < 0) {
neg = 1;
}
let result = pos;
for (let i = 1; i < len; i++) {
let temp = pos;
if(nums[i] > 0) {
pos = pos + 1;
neg = neg === 0 ? 0 : neg + 1;
} else if (nums[i] < 0) {
pos = neg === 0 ? 0 : neg + 1;
neg = temp + 1;
} else {
pos = 0;
neg = 0;
}
result = Math.max(result, pos)
}
return result
};