LeetCode 算法题【中等】152. 乘积最大子数组

语雀原文链接

1、LeetCode 链接

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

测试用例的答案是一个 32-位 整数。

 

示例 1:

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

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

提示:

1 <= nums.length <= 2 * 104
-10 <= nums[i] <= 10
nums 的任何子数组的乘积都 保证 是一个 32-位 整数

2、个人写法

  • 思路:暴力解法,遍历所有
  • 时间复杂度:O(N2)
  • 空间复杂度:O(1)
class Solution {
    public int maxProduct(int[] nums) {

        int length = nums.length;
        int max = Integer.MIN_VALUE;
        for (int i = 0; i < length; i++) {
            int mul = 1;
            for (int j = i; j < length; j++) {
                mul *= nums[j];
                if (mul > max) {
                    max = mul;
                }
            }
        }
        return max;
    }
}

3、官方写法

  • 思路:
  1. max[i] 表示以第i个元素为结尾的子数组的最大乘积
  2. min[i] 表示以第i个元素为结尾的子数组的最小乘积
  3. nums[i+1]表示第i+1的元素,那么max[i+1]
    1. 如果是正数,nums[i+1] * max[i] 则最大
    2. 如果是负数,nums[i+1] * min[i] 则最大
    3. 但是可能存在num[i+1] 这个元素自身 比max[i]大,比min[i]小;
    4. 例如数组[-3 5] max[0]=-3 min[0]=-3 max[1] = 5 min[1]=-15
    5. 例如数组[5 3] max[0]=5 min[0]=5 max[1] = 15 min[1]=3
  4. 最终就是在这3个数字中取最大值和最小值
    • max[i+1] = max(tempMax * nums[i], nums[i], tempMin * nums[i])
    • min[i+1] = min(tempMax * nums[i], nums[i], tempMin * nums[i])
  • 时间复杂度:O(N)
  • 空间复杂度:O(1)
class Solution {
    public int maxProduct(int[] nums) {

        int max = nums[0];
        int min = nums[0];
        int result = nums[0];

        int length = nums.length;
        for (int i = 1; i < length; i++) {

            int tempMax = max;
            int tempMin = min;

            // 3个数取最大值 tempMax * nums[i] 和 nums[i] 和 tempMin * nums[i]
            max = Math.max(tempMax * nums[i], Math.max(tempMin * nums[i], nums[i]));
            min = Math.min(tempMax * nums[i], Math.min(tempMin * nums[i], nums[i]));

            result = Math.max(max, result);

        }
        return result;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

代码充电宝

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

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

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

打赏作者

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

抵扣说明:

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

余额充值