LeetCode Maximum Length of Subarray With Positive Product

1567. Maximum Length of Subarray With Positive Product

Given an array of integers nums, find the maximum length of a subarray where the product of all its elements is positive.

A subarray of an array is a consecutive sequence of zero or more values taken out of that array.

Return the maximum length of a subarray with positive product.

Example 1:

Input: nums = [1,-2,-3,4]
Output: 4
Explanation: The array nums already has a positive product of 24.

Example 2:

Input: nums = [0,1,-2,-3,-4]
Output: 3
Explanation: The longest subarray with positive product is [1,-2,-3] which has a product of 6.
Notice that we cannot include 0 in the subarray since that'll make the product 0 which is not positive.

Example 3:

Input: nums = [-1,-2,-3,0,1]
Output: 2
Explanation: The longest subarray with positive product is [-1,-2] or [-2,-3].

Example 4:

Input: nums = [-1,2]
Output: 1

Example 5:

Input: nums = [1,2,3,5,-6,4,0,10]
Output: 4

Constraints:

  • 1 <= nums.length <= 10^5
  • -10^9 <= nums[i] <= 10^9

给一个数组,包含正数、负数和0,问最长连乘结果为正的长度是多少。

本题与LeetCode Maximum Product Subarray类似,要注意负负得正的情况。首先是传统DP好理解方法:设置dp_pos和dp_neg两个数组,分别表示遍历到i时,当前的最长连乘为正的长度和最长连乘为负的长度。则对于第i个位置,如果nums[i]是正数,则dp_pos直接+1;对于dp_neg,如果前一刻已经是连乘为负,即dp_neg[i-1]>0,则在前一刻基础上再乘以nums[i]还是负,所以负数长度可变长,即dp_neg+1;如果前一刻没有连乘为负,则增加一个正数也不会使连乘为负的长度增加,所以dp_neg=0。类似的可以讨论num[i]为负数的情况。如果nums[i]==0,则dp_pos和dp_neg都重置为0。

完整代码如下:

class Solution {
public:
    int getMaxLen(vector<int>& nums) {
        int n = nums.size();
        vector<int> dp_pos(n, 0), dp_neg(n, 0);
        if(nums[0] > 0) dp_pos[0] = 1;
        else if(nums[0] < 0) dp_neg[0] = 1;
        int ans = dp_pos[0];
        for(int i = 1; i < n; ++i) {
            if(nums[i] > 0) {
                dp_pos[i] = dp_pos[i - 1] + 1;
                dp_neg[i] = dp_neg[i - 1] > 0 ? dp_neg[i - 1] + 1 : 0;
            } else if(nums[i] < 0) {
                dp_pos[i] = dp_neg[i - 1] > 0 ? dp_neg[i - 1] + 1 : 0;
                dp_neg[i] = dp_pos[i - 1] + 1;
            }
            ans = max(ans, dp_pos[i]);
        }
        return ans;
    }
};

本代码提交AC,用时268MS。

因为DP只用到上一刻的状态,所以不用数组存储也可以,节省内存版本如下,不过需要注意tmp=pos_len保存上一刻的pos_len状态。

class Solution {
public:
    int getMaxLen(vector<int>& nums) {
        int n = nums.size();
        int pos_len = 0, neg_len = 0;
        if(nums[0] > 0) pos_len = 1;
        else if(nums[0] < 0) neg_len = 1;
        int ans = pos_len;
        for(int i = 1; i < n; ++i) {
            if(nums[i] > 0) {
                ++pos_len;
                neg_len = neg_len > 0 ? neg_len + 1 : 0;
            } else if(nums[i] < 0) {
                int tmp = pos_len;
                pos_len = neg_len > 0 ? neg_len + 1 : 0;
                neg_len = tmp + 1;
            } else if(nums[i] == 0) {
                pos_len = neg_len = 0;
            }
            ans = max(ans, pos_len);
        }
        return ans;
    }
};

本代码提交AC,用时368MS。

Leave a Reply

Your email address will not be published. Required fields are marked *