LeetCode 862.和至少为k的最短子数组 题解
题目描述
给你一个整数数组 nums ,请你找出数组中乘积最大的非空连续子数组(该子数组中至少包含一个数字),并返回该子数组所对应的乘积。
测试用例的答案是一个 32-位 整数。
子数组 是数组的连续子序列。
示例 1:
1 | 输入: nums = [2,3,-2,4] |
示例 2:
1 | 输入: nums = [-2,0,-1] |
算法1
(暴力 + 前缀积优化) $O(n^2)$
如果使用通常的暴力算法,那么需要枚举区间的左端点,再枚举长度,这样的话需要的时间、空间复杂度都很高
那么此时可以想到,使用前缀积的思想来进行优化
与前缀和类似,可以预先处理出来数组的前缀积,再依次枚举区间的长度、端点就可以优化掉一维
算法2
(DP) $O(n)$
利用动态规划的思想:
很容易从题目描述中看出,选择每个点作为子数组终点时,代表的是一系列选择的结果,因此需要使用动态规划来表示一系列结果
由于本题中是求子数组的最大乘积,而乘法有着负负得正的性质,因此在每次更新状态时,要考虑到当前元素的正负性对答案的赢想,所以需要保存一个最小值,方便与负数相乘而得到最大的乘积
1 | class Solution { |
算法3
(DP + 滚动数组) $O(n)$
在上一题中,能够发现所有的情况只会由上一个状态更新而来,而其余情况的存储是多余的,因此不需要使用数组来存储每种状态,可以使用两个变量来保存上一次情况的结果,从而更新下一次状态即可
经过滚动数组优化之后,可以将空间复杂度降为 $O(1)$
1 | class Solution { |
All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.