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;
}
}
解题思路
- 动态规划: 使用两个变量
maxProd和minProd来分别记录到当前位置的最大乘积和最小乘积。因为乘以负数可能会使最小乘积变成最大乘积。- 迭代: 遍历数组,对于每个元素,更新当前的最大和最小乘积。然后根据当前元素的符号决定如何更新它们。
- 结果: 在遍历过程中,维护一个全局最大乘积。
复杂度分析
- 时间复杂度:O(n),其中 n 是数组 nums 的长度。我们只需遍历数组一次。
- 空间复杂度:O(1),只使用了常数个额外的空间来存储变量。
注:题目来源leetcode网站

4958

被折叠的 条评论
为什么被折叠?



