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

103 阅读2分钟

零、原题展示

题目链接:leetcode.cn/problems/ma… image.png

一、思路

1.1 自己的思考

想不到,直接前半部分官方的题解:leetcode.cn/problems/ma… 看到要用两个数组positive、negative做这道题。

1.2 对了解到的思路进行进一步分析

在明确了要用两个数组解决这道题目的时,开始对两个数组进行分析。 两个数组中的作用

  • positive用于记录乘积为正数的连续长度
  • negative用于记录乘积为负数的连续长度

其次,对传入的nums数组进行遍历,分析有多少种情况
情况一:nums[i] > 0
情况二:nums[i] < 0
情况三:nums[i] == 0

1.2.1 情况一:当nums[i] > 0时

原本乘积为正的子序列乘上nums[i]仍然为正。 原本乘积为负的子序列乘上nums[i]仍然为负。

表达式初步可以推出为:

positive[i] = positive[i - 1] + 1
negative[i] = negative[i - 1] + 1
注意特殊情况:
  1. positive[i - 1]为0时,positive[i]仍为positive[i - 1] + 1
  2. negative[i - 1]为0时,negative[i]显然不能为negative[i - 1] + 1,且应该将negative[i]设置为0,这是因为negative[i - 1]为0且当前的nums[i]为正数,因此该位置的乘积为负数的连续长度也为0。

因此最终求得的表达式如下:

positive[i] = positive[i - 1] + 1
negative[i] = negative[i - 1] + 1 (negative[i - 1] != 0)
            = 0                   (negative[i - 1] == 0)

1.2.2 情况二:当nums[i] < 0时

原本乘积为正的子序列乘上nums[i]会变为负。 原本乘积为负的子序列乘上nums[i]会变为正。

表达式初步可以推出为:

positive[i] = negative[i - 1] + 1
negative[i] = positive[i - 1] + 1
注意特殊情况:
  1. negative[i - 1]为0时,positive[i]显然不能为negative[i - 1] + 1,且应该将positive[i]设置为0,这是因为negative[i - 1]为0且当前的nums[i]为负数。因此该位置的乘积为正数的连续长度也为0。
  2. positive[i - 1]为0,则negative[i]仍为positive[i - 1] + 1

因此最终求得的表达式如下:

positive[i] = negative[i - 1] + 1 (negative[i - 1] != 0)
            = 0                   (negative[i - 1] == 0)
negative[i] = positive[i - 1] + 1 

1.2.3 情况三:当nums[i] == 0时

显然,无论是连续的乘积为正还是为负,在该位置的对应长度均为0

因此直接求得的表达式如下:

positive[i] = 0
negative[i] = 0

二、代码(Java)

public static int getMaxLen(int[] nums) {
        if (nums.length == 1) {
            if (nums[0] > 0) {
                return 1;
            } else {
                return 0;
            }
        }
        int positive[] = new int[nums.length], negative[] = new int[nums.length];
        for (int i = 0; i < nums.length; i++) {
            positive[i] = 0;
            negative[i] = 0;
        }
        if (nums[0] > 0) {
            positive[0] = 1;
        } else if(nums[0] < 0) {
            negative[0] = 1;
        }

        for (int i = 1; i < nums.length; i++) {
//            情况一:
            if (nums[i] > 0) {
                positive[i] = positive[i - 1] + 1;
                if (negative[i - 1] == 0) {
                    negative[i] = 0;
                } else {
                    negative[i] = negative[i - 1] + 1;
                }
//            情况二:
            } else if (nums[i] < 0) {
                if (negative[i - 1] == 0) {
                    positive[i] = 0;
                } else {
                    positive[i] = negative[i - 1] + 1;
                }
                negative[i] = positive[i - 1] + 1;
//            情况三:
            } else {
                positive[i] = 0;
                negative[i] = 0;
            }
        };
//        System.out.println(Arrays.toString(positive));
//        System.out.println(Arrays.toString(negative));
//            排序一下,输出最大值
        Arrays.sort(positive);
        return positive[positive.length - 1];
    }

三、优化

由于代码中使用了排序,即:要取最大值。那么我们可以设置一个变量获取最大值就行。优化后的代码如下:

public static int getMaxLen(int[] nums) {
        if (nums.length == 1) {
            if (nums[0] > 0) {
                return 1;
            } else {
                return 0;
            }
        }
        int positive[] = new int[nums.length], negative[] = new int[nums.length];
        for (int i = 0; i < nums.length; i++) {
            positive[i] = 0;
            negative[i] = 0;
        }
        if (nums[0] > 0) {
            positive[0] = 1;
        } else if(nums[0] < 0) {
            negative[0] = 1;
        }
        // ---------------
        // 优化:用于获取最大值
        // ---------------       
        int maxValue = 0; 
        for (int i = 1; i < nums.length; i++) {
//            情况一:
            if (nums[i] > 0) {
                positive[i] = positive[i - 1] + 1;
                if (negative[i - 1] == 0) {
                    negative[i] = 0;
                } else {
                    negative[i] = negative[i - 1] + 1;
                }
//            情况二:
            } else if (nums[i] < 0) {
                if (negative[i - 1] == 0) {
                    positive[i] = 0;
                } else {
                    positive[i] = negative[i - 1] + 1;
                }
                negative[i] = positive[i - 1] + 1;
//            情况三:
            } else {
                positive[i] = 0;
                negative[i] = 0;
            }
            // ---------------
            // 优化:每次遍历比较最大值情况,更新最大值
            // --------------- 
            if (maxValue < positive[i]) {
                maxValue = positive[i];
            }
        };
//        System.out.println(Arrays.toString(positive));
//        System.out.println(Arrays.toString(negative));
//            排序一下,输出最大值
//        Arrays.sort(positive);
        return maxValue;
    }

四、运行结果比较

未优化前:

image.png

优化后:

image.png