题目
Given an integer array nums, find the contiguous subarray within an array (containing at least one number) which has the largest product.
Example 1:
Input: [2,3,-2,4]
Output: 6
Explanation: [2,3] has the largest product 6.
Example 2:
Input: [-2,0,-1]
Output: 0
Explanation: The result cannot be 2, because [-2,-1] is not a subarray.
思路与解法
这道题让我们从数组中寻找一个连续子序列使得其累乘所得的积最大。这道题与最大连续子数列和十分相似(最大连续子数列和的状态转移方程为dp[i]=max(num[i], dp[i-1]+num[i]
,其中状态 dp[i]
表示以 num[i]
作为末尾的连续子数列的最大和))。
所以,我们可以采用同样的想法,使用dp[i]
表示以num[i]
作为末尾的连续子数列的最大积。由于在乘法中,两个负数相乘结果为正,所以可能存在一个很小的负数积在以num[i]
为末尾时此子数列得到一个更大的积。所以我们既需要维护最大积,也需要维护最小积。可以分别用dp[i][0]
或者dp[i][1]
来表示。
代码实现(Go)
const INT_MAX = int(^uint(0) >> 1)
const INT_MIN = ^INT_MAX
// 自定义max函数
func max(nums ...int) (maxx int) {
maxx = INT_MIN
for _, num := range(nums) {
if maxx < num {
maxx = num
}
}
return
}
// 自定义min函数
func min(nums ...int) (minn int) {
minn = INT_MAX
for _, num := range(nums) {
if minn > num {
minn = num
}
}
return
}
func maxProduct(nums []int) int {
lenNums := len(nums)
// 并没有使用数组来存储状态
localMin := nums[0]
localMax := nums[0]
// res存储最大值
res := nums[0]
for i:=1; i<lenNums; i++ {
tempMax := localMax
// 以num[i]为结尾的子数列的最大值为localMax*nums[i]、localMin*nums[i]、nums[i]三者中的一个
localMax = max(localMax * nums[i], localMin * nums[i], nums[i])
// 以num[i]为结尾的子数列的最小值为tempMax *nums[i]、localMin*nums[i]、nums[i]三者中的一个
localMin = min(tempMax * nums[i], localMin * nums[i], nums[i])
// 更新res
res = max(localMax, res)
}
return res
}