202111-28更文-leetcode152:乘积最大子数组

这是我参与11月更文挑战的第28天,活动详情查看:2021最后一次更文挑战

leetcode152:乘积最大子数组

前文

本文为本人在leetcode中解题的思路,并非代表最佳解决方案。

题目信息

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

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

解题思路分析

根据题目信息所述,我们这里有一个数组,同时可能存储正整数与负整数。由于该题目要求为计算连续乘积最大的子数组,由于存在正数与负数的两种情况,因此需要对正数负数分别进行记录。本题主要的解题方向是采取动态规划的思路,对于每个节点位置,均获取至今为止的连续数组与最小连续数组。通过mx与mn变量,也就是max和min变量,分别记录至今为止最后一个连续周期内的最大值与最小值。考虑到正负的角度,所以需要获取最小值乘以当前节点、最大值乘以当前节点与result中较大的值作至今为止的最大数组乘积结果。而上述的处理过程,也就是动态规划中对应的状态转移方程的内容。随着dp数组的遍历,即可得到每个位置的最大值。由于我们对于中间节点的数据没有要求,因此采用变量进行存储,优化该算法的空间复杂度。至此,该问题解决完毕。

public int maxProduct(int[] nums) {
    if(nums.length == 0){
        return 0;
    }else if(nums.length == 1){
        return nums[0];
    }
    int max = nums[0];
    int min = nums[0];
    int result = nums[0];
    for (int i = 1; i < nums.length; i++) {
        int mx = max;
        int mn = min;
        max = Math.max(mx * nums[i],Math.max(nums[i],mn * nums[i]));
        min = Math.min(mn * nums[i],Math.min(nums[i],mx * nums[i]));
        result = Math.max(max,result);
    }
    return result;
}
复制代码

复杂度分析

  • 时间复杂度 o(n)
  • 空间复杂度 o(1)

后记

  • 千古兴亡多少事?悠悠。不尽长江滚滚流。

猜你喜欢

转载自juejin.im/post/7035608966348406820