题解 | #乘积为正数的最长连续子数组#

乘积为正数的最长连续子数组

https://www.nowcoder.com/practice/0112b9b5a09048d89309f55ea666db91?tpId=230&tqId=2378149&ru=/exam/oj&qru=/ta/dynamic-programming/question-ranking&sourceUrl=%2Fexam%2Foj

遍历到数组元素时,分别考虑3种情况:正数、0、负数

  1. 正数,没什么好说的,dp[i] = dp[i-1] + 1
  2. 0,直接重置 dp 数组和 negativeCnt,dp[i] = 0,negativeCnt = 0 (记录负数的个数)
  3. 负数,首先将负数个数加1,然后判断负数个数是偶数还是奇数
  4. 奇数,首先当前 dp 值置为 0 —— dp[i] = 0,然后记录此时 dp[i-1] 的值 —— int pre = dp[i - 1]
  5. 偶数,则需要加上上一个负数前面的最长连续子数组长度和两个负数的个数 —— dp[i] = dp[i-1] + pre + 2

定义初始状态:根据数组第一个元素 nums[0] 分别判断 dp[0] 和 negativeCnt

  1. dp[0] = nums[0] > 0 ? 1 : 0
  2. negativeCnt = nums[0] < 0 ? 1 : 0

最后返回 dp 数组中的最大值(ps:dp[i] 表示以下标 nums[i] 结尾的子数组,其乘积为正数的长度)

import java.util.Scanner;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        int[] nums = new int[n];
        for (int i = 0; i < nums.length; i++) {
            nums[i] = in.nextInt();
        }

        System.out.println(maxProduct(nums));
    }

    public static int maxProduct(int[] nums) {
        int result = 0;
        int pre = 0;    // 记录奇数个负数时dp[i-1]的值

        int[] dp = new int[nums.length];
        dp[0] = nums[0] > 0 ? 1 : 0;
        int negativeCount = nums[0] < 0 ? 1 : 0;	// 记录负数的个数
        for (int i = 1; i < nums.length; i++) {
            if (nums[i] > 0) {
                dp[i] = dp[i - 1] + 1;
            } else {   // nums[i] <= 0
                if (nums[i] == 0) {
                    negativeCount = 0;
                    dp[i] = 0;
                } else { // nums[i] < 0
                    negativeCount++;
                    if ( negativeCount % 2 == 0) {
                        dp[i] = dp[i - 1] + pre + 2;  // 偶数个负数时,加上第奇数个负数和当前负数,故加2
                    } else {
                        dp[i] = 0;
                        pre = dp[i - 1];    // 记录奇数个负数时dp[i-1]的值
                    }
                }
            }

            result = Math.max(result, dp[i]);
        }
        return result;
    }
}

全部评论

相关推荐

11-09 01:22
已编辑
东南大学 Java
高级特工穿山甲:羡慕,我秋招有家企业在茶馆组织线下面试,约我过去“喝茶详谈”😢结果我去了发现原来是人家喝茶我看着
点赞 评论 收藏
分享
已老实求offer😫:有点像徐坤(没有冒犯的意思哈)
点赞 评论 收藏
分享
点赞 2 评论
分享
牛客网
牛客企业服务