1567. Maximum Length of Subarray With Positive Product
Description
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].
Constraints:
1 <= nums.length <= 105-109 <= nums[i] <= 109
Solutions
Solution 1: Dynamic Programming
Thinking
Find the longest subarray whose product is positive. \(n\le 10^5\), so checking every pair overflows and times out. Zeros split the array and a minus only flips the sign, so we may store, at each end, the longest positive and negative products.
Let \(f[i]\) and \(g[i]\) be those two lengths ending at \(i\). A positive value keeps the previous signs; a negative value swaps them; a zero breaks both. The answer is the maximum \(f[i]\).
We define two arrays \(f\) and \(g\) of length \(n\), where \(f[i]\) represents the length of the longest subarray ending at \(\textit{nums}[i]\) with a positive product, and \(g[i]\) represents the length of the longest subarray ending at \(\textit{nums}[i]\) with a negative product.
Initially, if \(\textit{nums}[0] > 0\), then \(f[0] = 1\), otherwise \(f[0] = 0\); if \(\textit{nums}[0] < 0\), then \(g[0] = 1\), otherwise \(g[0] = 0\). We initialize the answer \(ans = f[0]\).
Next, we iterate through the array \(\textit{nums}\) starting from \(i = 1\). For each \(i\), we have the following cases:
- If \(\textit{nums}[i] > 0\), then \(f[i]\) can be transferred from \(f[i - 1]\), i.e., \(f[i] = f[i - 1] + 1\), and the value of \(g[i]\) depends on whether \(g[i - 1]\) is \(0\). If \(g[i - 1] = 0\), then \(g[i] = 0\), otherwise \(g[i] = g[i - 1] + 1\);
- If \(\textit{nums}[i] < 0\), then the value of \(f[i]\) depends on whether \(g[i - 1]\) is \(0\). If \(g[i - 1] = 0\), then \(f[i] = 0\), otherwise \(f[i] = g[i - 1] + 1\), and \(g[i]\) can be transferred from \(f[i - 1]\), i.e., \(g[i] = f[i - 1] + 1\).
- Then, we update the answer \(ans = \max(ans, f[i])\).
After the iteration, we return the answer \(ans\).
The time complexity is \(O(n)\), and the space complexity is \(O(n)\). Here, \(n\) is the length of the array \(\textit{nums}\).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | |
Solution 2: Dynamic Programming (Space Optimization)
Thinking
Each state uses only the previous \(f\) and \(g\), so two scalars replace the arrays. Time stays linear and extra memory becomes constant.
We observe that for each \(i\), the values of \(f[i]\) and \(g[i]\) only depend on \(f[i - 1]\) and \(g[i - 1]\). Therefore, we can use two variables \(f\) and \(g\) to record the values of \(f[i - 1]\) and \(g[i - 1]\), respectively, thus optimizing the space complexity to \(O(1)\).
The time complexity is \(O(n)\), where \(n\) is the length of the array \(\textit{nums}\). The space complexity is \(O(1)\).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | |