leetcode hot100【LeetCode 152. 乘积最大子数组】java实现

LeetCode 152. 乘积最大子数组

题目描述

给你一个整数数组 nums,请你找出数组中乘积最大的连续子数组(该子数组中至少包含一个数字),并返回该子数组所对应的乘积。

示例 1:

输入: [2,3,-2,4]
输出: 6
解释: 子数组 [2,3] 有最大乘积 6。

示例 2:

输入: [-2,0,-1]
输出: 0
解释: 结果不能为 2, 因为 [-2,-1] 不是子数组。

Java 实现代码

class Solution {
    public int maxProduct(int[] nums) {
        // 首先判断数组是否为空,如果数组长度为 0,直接返回 0,因为空数组不存在子数组,最大乘积自然为 0
        if (nums.length == 0) return 0;

        // 初始化最大乘积 maxProd 为数组的第一个元素,因为单个元素也可以看作是一个子数组,其乘积就是该元素本身
        // 例如,对于数组 [2, 3, -2, 4],初始时 maxProd 就是 2
        int maxProd = nums[0];
        // 初始化最小乘积 minProd 为数组的第一个元素,后续在遍历过程中,负数的存在会使乘积的正负性发生变化,所以需要记录最小乘积
        // 同样对于数组 [2, 3, -2, 4],初始时 minProd 也是 2
        int minProd = nums[0];
        // 初始化最终结果 result 为最大乘积,因为目前最大乘积就是第一个元素
        // 对于数组 [2, 3, -2, 4],初始时 result 为 2
        int result = maxProd;

        // 从数组的第二个元素开始遍历,因为第一个元素已经在初始化时处理过了
        for (int i = 1; i < nums.length; i++) {
            // 判断当前元素是否为负数
            if (nums[i] < 0) {
                // 如果当前元素是负数,那么乘以最大乘积会得到一个更小的值,乘以最小乘积会得到一个更大的值
                // 所以需要交换最大乘积和最小乘积
                // 例如,当遍历到数组 [2, 3, -2, 4] 中的 -2 时,此时 maxProd 可能是 6(2 * 3),minProd 是 2
                // 交换后,maxProd 变为 2,minProd 变为 6
                int temp = maxProd;
                maxProd = minProd;
                minProd = temp;
            }

            // 更新以当前元素结尾的最大乘积
            // 取当前元素、当前元素乘以之前的最大乘积中的较大值
            // 例如,当遍历到数组 [2, 3, -2, 4] 中的 3 时,maxProd 初始为 2,计算 Math.max(3, 2 * 3) 得到 6
            maxProd = Math.max(nums[i], maxProd * nums[i]);
            // 更新以当前元素结尾的最小乘积
            // 取当前元素、当前元素乘以之前的最小乘积中的较小值
            // 例如,当遍历到数组 [2, 3, -2, 4] 中的 3 时,minProd 初始为 2,计算 Math.min(3, 2 * 3) 得到 3
            minProd = Math.min(nums[i], minProd * nums[i]);

            // 更新最终结果,取之前的结果和当前最大乘积中的较大值
            // 例如,当遍历到数组 [2, 3, -2, 4] 中的 3 时,result 初始为 2,maxProd 变为 6,更新后 result 为 6
            result = Math.max(result, maxProd);
        }

        // 遍历结束后,result 即为最大乘积子数组的乘积
        return result;
    }
}

解题思路

  1. 动态规划: 使用两个变量 maxProdminProd 来分别记录到当前位置的最大乘积和最小乘积。因为乘以负数可能会使最小乘积变成最大乘积。
  2. 迭代: 遍历数组,对于每个元素,更新当前的最大和最小乘积。然后根据当前元素的符号决定如何更新它们。
  3. 结果: 在遍历过程中,维护一个全局最大乘积。

复杂度分析

  • 时间复杂度:O(n),其中 n 是数组 nums 的长度。我们只需遍历数组一次。
  • 空间复杂度:O(1),只使用了常数个额外的空间来存储变量。

注:题目来源leetcode网站

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

DataCrafter

你的鼓励是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值