leetcode-1567. 乘积为正数的最长子数组长度


题目

1567. 乘积为正数的最长子数组长度

解法

解法一

算是贪心吧?
遍历的方向从前往后也是一样的道理,只不过当时写代码的时候从后往前想的,就这么写了

class Solution {
    
    /**
     * @param Integer[] $nums
     * @return Integer
     */
    function getMaxLen($nums) {
        $len = count($nums);
        if ($len == 1) {
            return $nums[0] > 0 ? 1 : 0;
        }
        
        $lastZeroIndex    = $len;
        $lastZeroMinusCnt = 0;
        $lastMinusIndex   = -1;
        
        $maxDis = 0;
        
        for ($i = $len - 1; $i >= 0; $i--) {
            if ($nums[$i] == 0) {
                $lastZeroIndex    = $i;
                $lastZeroMinusCnt = 0;
                $lastMinusIndex   = -1;
                continue;
            }
            
            if ($nums[$i] < 0) {
                // 距离上一个0或者尾部的负数数量
                $lastZeroMinusCnt++;
                if ($lastMinusIndex == -1) {
                    // 从0或者尾部过来的第一个负数位置
                    $lastMinusIndex = $i;
                }
            }
            
            if ($lastZeroMinusCnt % 2 == 0) {
                // 负数个数为偶数,可以到结尾或者0的位置
                $maxDis = max($maxDis, $lastZeroIndex - $i);
            } else {
                // 负数个数为奇数,只能到最后一个负数之前的位置
                $maxDis = max($maxDis, $lastMinusIndex - $i);
            }
        }
        
        return $maxDis;
    }
}

dp

大概思想是:
维护两个节点,一个是带负数的长度,一个是不带负数的长度

参考

官方题解