题目描述
链接: https://leetcode-cn.com/problems/maximum-length-of-subarray-with-positive-product/
给定一个整数数组nums, 求乘积为正数的最长子数组的长度
示例1:
输入: [1, -2, -3, 4]
输出: 4
数组本身乘积就是正数
示例2:
输入: [0, 1, -2, -3, -4]
输出: 3
最长乘积为整数的子数组为[1, -2, -3]
解题思路
使用动态规划来计算乘积为正数的最长子数组长度.
使用两个数组positive和negative, 表示在第i个位置时, 乘积为正数的最长子数组长度 和 乘积为负数的最长子数组长度.
由于数组中可能存在0, 所以对于值为0时还需要特殊处理.
对于位置i,
如果
nums[i]>0
即为正数那么
nums[i]
与前面的数组相乘时不会改变符号. 即使前面乘积为0, 那么nums[i]
也可以单独作为子数组, 长度为1.所以
1
positive[i] = positive[i-1] + 1
对于乘积为负数的最长子数组长度, 如果前面的乘积为0, 那么这时仍然是0. 如果前面不为0, 这时就等于前面的长度加1.
所以
1
2negative[i] = negative[i-1] + 1 (negative[i-1]>0)
negative[i] = 0 (negative[i-1]=0)如果
nums[i]
为负数那么
nums[i]
与前面的数组相乘就会改变符号. 所以当前位置的正数长度应该为上一次的负数长度加1, 同时需要判断上次的负数长度是否为0.1
2positive[i] = negative[i-1]+1 (negative[i-1]>0)
positive[i] = 0 (negative[i-1]=0)当前位置的负数长度应该为上一次正数长度加1
1
negative[i] = positive[i-1]+1
如果
nums[i]=0
这时乘积为0, 所以
1
negative[i] = positive[i] = 0
最后求positive数组中的最大值
代码实现
1 | public int getMaxLen(int[] nums) { |
优化
动态规划的一个常规优化, 递推方程只与上一次的状态有关, 所以我们只需要临时变量保存上一次的状态
1 | public int getMaxLen(int[] nums) { |