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

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

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;
    }
}

全部评论

相关推荐

小红书 后端开发 总包n+8w+期权
点赞 评论 收藏
分享
10-15 15:00
潍坊学院 golang
跨考小白:这又不是官方
投递拼多多集团-PDD等公司10个岗位
点赞 评论 收藏
分享
头像
11-07 01:12
重庆大学 Java
精致的小松鼠人狠话不多:签哪了哥
点赞 评论 收藏
分享
点赞 2 评论
分享
牛客网
牛客企业服务