O(n) Greedy sliding window with explanation
Intuition\nThe key insight for this problem is understanding how the product of integers behaves:\n\n- A positive product keeps growing with positive integers.\
# Intuition\nThe key insight for this problem is understanding how the product of integers behaves:\n\n- A positive product keeps growing with positive integers.\n- A zero resets the progress entirely.\n- Negatives are tricky: an even number of negatives results in a positive product, while an odd number results in a negative product.\n \n## To solve this problem, we can use a sliding window approach:\n\nExpand the window as long as the product remains positive.\nShrink the window only when the product becomes negative and cannot be fixed.\n\n# Approach\n1. Precompute Negatives:\n* Create an array that stores the count of negative numbers from the current position to the right.\n* **Note:** A zero resets the count as it breaks continuity.\n\n2. Initialize Sliding Window:\n* Set two pointers (l and r) at the start of the array.\n* Maintain a counter to track the number of negative values in the current window.\n\n3. Expand the Sliding Window:\n* Skip any zeros by moving both pointers to the next position and resetting the counter.\n* If the current value is negative, increment the counter.\n\n4. Shrink the Window When Necessary:\n* If the number of negatives in the current window is odd and there are no additional negatives available to balance it (from the precomputed array), move the left pointer to shrink the window.\n\n5. Update the Result:\n* If the product is positive (i.e., the number of negatives in the window is even) and the window size is larger than the previous result, update the result.\n\n6. Return the Maximum Window Size:\n* Once the loop completes, the result will contain the size of the largest subarray with a positive product.\n\n# Complexity\n- Time complexity: O(n)\n\n- Space complexity: O(n)\n\n# Code\n```javascript []\n/**\n * @param {number[]} nums\n * @return {number}\n */\nvar getMaxLen = function(nums) {\n    const n = nums.length;\n    const negativesToRight = new Array(n).fill(0);\n\n    // precalculate available negatives from current position to the right\n    for (let i = n-2; i >= 0; i--) {\n        // 0 reset number of negatives\n        if (nums[i] === 0) {\n            negativesToRight[i] = 0;\n        } else {\n            negativesToRight[i] = negativesToRight[i+1] + (nums[i+1] < 0 ? 1 : 0);   \n        }\n    }\n\n    let l = 0;\n    let r = 0;\n    let negativesToLeft = 0;\n    let result = 0;\n\n    while (r < n) {\n        // skip 0 as they reset product to 0\n        while (r < n && nums[r] === 0) {\n            r++;\n            l = r;\n            negativesToLeft = 0;\n        }\n\n        // [0,0,0,0] covers this case\n        if (r === n) break;\n\n\n        if (nums[r] < 0) {\n            negativesToLeft++\n        }\n\n        // start moving left pointer only when there\'s no available negatives to the right\n        // in other cases product of two negatives will give positive\n        while (negativesToLeft % 2 === 1 && l < r && negativesToRight[r] === 0) {\n            if (nums[l] < 0) {\n                negativesToLeft--\n            }\n            l++\n        }\n\n        // update result when product is positive\n        if (negativesToLeft % 2 === 0) {\n            result = Math.max(result, r-l+1)\n        }\n        r++;\n    }\n\n    return result;\n};\n```
['Greedy', 'Sliding Window', 'Prefix Sum', 'JavaScript']