LeetCode 152. 乘积最大子数组
题目描述
给你一个整数数组 nums ,请你找出数组中乘积最大的非空连续 子数组(该子数组中至少包含一个数字),并返回该子数组所对应的乘积。
测试用例的答案是一个 32-位 整数。
请注意,一个只包含一个元素的数组的乘积是这个元素的值。
示例
示例 1:
输入: nums = [2,3,-2,4] 输出: 6 解释: 子数组 [2,3] 有最大乘积 6。
示例 2:
输入: nums = [-2,0,-1] 输出: 0 解释: 结果不能为 2, 因为 [-2,-1] 不是子数组。
解法
1.暴力
解题思路
这是一个暴力解法,通过两层循环遍历所有可能的连续子数组,对于每个起始位置,计算从该位置开始的所有子数组的乘积,在计算过程中不断更新找到的最大乘积。
class Solution {
public:int maxProduct(vector<int>& nums) {int n = nums.size();int ans = nums[0];for(int i = 0;i < n;i ++){int m = nums[i];ans = max(m,ans);for(int j = i + 1;j < n;j ++){m *= nums[j];ans = max(m,ans);}}return ans;}
};时间复杂度O(N^2),空间复杂度O(1)
2.动态规划
解题思路:
下面这段通过同时维护当前的最大乘积和最小乘积,利用负数相乘"负负得正"的特性,在单次遍历中动态跟踪所有可能的子数组乘积极值,从而高效找到全局最大乘积。
class Solution {
public:int maxProduct(vector<int>& nums) {int n = nums.size();int maxProd = nums[0];int minProd = nums[0];int result = nums[0];for (int i = 1; i < n; i++) {// 由于存在负数,需要同时维护最大和最小值int temp = maxProd;maxProd = max({nums[i], maxProd * nums[i], minProd * nums[i]});minProd = min({nums[i], temp * nums[i], minProd * nums[i]});result = max(result, maxProd);}return result;}
};时间复杂度O(N),空间复杂度O(1)
