乘积最大子序和
力扣第152题:https://leetcode-cn.com/problems/maximum-product-subarray/
给定一个整数数组 nums ,找出一个序列中乘积最大的连续子序列(该序列至少包含一个数)。
示例 1:
输入: [2,3,-2,4]
输出: 6
解释: 子数组 [2,3] 有最大乘积 6。
示例 2:
输入: [-2,0,-1]
输出: 0
解释: 结果不能为 2, 因为 [-2,-1] 不是子数组。
1. 类似指针的解法
参考力扣第53题最大子序和的其中一种双指针解法,这道题同样可以用类似指针的解法
- 首先定义一个res记录最大的子序和,cur_pos记录当前的乘积
- 然后cur_pos依次累乘, 每一次的结果都有三种情况:
- cur_pos等于0, 这时候要重新将指针偏移后一位
- cur_pos大于0, 这时候要更新res的结果,就是和cur_pos比较大小
- cur_pos小于0, 负负得正,需要找到指针前面最大的负数,相除就变为最大
1 | class Solution: |
1.1 复杂度分析
时间复杂度:遍历整个数组的时间复杂度为O(N)
空间复杂度:没有用到额外的数据结构,所以空间复杂度为O(1)
2. 动态规划解决
不难发现,每一个元素的乘积,最大值只可能在自身或者自身与上一次的累乘之中
公式如下:
dp_max[i] = Math.max(nums[i-1],dp_max[i-1]*nums[i-1])
因为存在负数,所以当这个元素为负数是,其最大乘积可能是与上一次最小乘积相乘
所以不仅要定义一个变量存储最大当前的最大累乘,还要定义一个变量存储当前的最小累乘
1 | class Solution: |
2.1 复杂度分析
时间复杂度:遍历整个数组的时间复杂度为O(N)
空间复杂度:没有用到额外的数据结构,所以空间复杂度为O(1)