Discuss:www.cnblogs.com/grandyang/p…
Given an integer array nums, find a contiguous non-empty subarray within the array that has the largest product, and return the product.
It is guaranteed that the answer will fit in a 32-bit integer.
A subarray is a contiguous subsequence of the array.
Example 1:
Input: nums = [2,3,-2,4]
Output: 6
Explanation: [2,3] has the largest product 6.
Example 2:
Input: nums = [-2,0,-1]
Output: 0
Explanation: The result cannot be 2, because [-2,-1] is not a subarray.
Constraints:
1 <= nums.length <= 2 * 104-10 <= nums[i] <= 10- The product of any prefix or suffix of
numsis guaranteed to fit in a 32-bit integer.
解法一:
使用动态规划求解。要用到一个二维 dp 数组,其中 dp[i][0] 表示子数组 [0, i] 范围内并且一定包含 nums[i] 数字的最大子数组乘积,dp[i][1] 表示子数组 [0, i] 范围内并且一定包含 nums[i] 数字的最小子数组乘积,初始化时 dp[i][0] 和 dp[i][1] 都初始化为 nums[0]。那么从数组的第二个数字开始遍历,此时的最大值和最小值只会在这三个数字之间产生,即 dp[i-1][0]*nums[i],dp[i-1][1]*nums[i],和 nums[i]。所以用三者中的最大值来更新 dp[i][0],用最小值来更新 dp[i][1],然后用 dp[i][0] 来更新结果 res 即可,由于最终的结果不一定会包括 nums[n-1] 这个数字,所以 dp[n-1][0] 不一定是最终解,不断更新的结果 res 才是。我们还可以做空间优化,不需要记录每一个 nums[i] 对应的最大乘积和最小乘积,只需要记录前一个的最大乘积和最小乘积即可,参见代码如下:
class Solution {
fun maxProduct(nums: IntArray): Int {
val numbersSize = nums.size
val dp = Array(size = 2, init = { IntArray(size = 2, init = { nums[0] }) })
var result = nums[0]
for (i in 1 until nums.size) {
val x = i % 2
val y = (i - 1) % 2
dp[x][0] = getMaxFromThreeNumer(dp[y][0] * nums[i], dp[y][1] * nums[i], nums[i])
dp[x][1] = getMinFromThreeNumer(dp[y][0] * nums[i], dp[y][1] * nums[i], nums[i])
result = Math.max(dp[x][0], result)
}
return result
}
private fun getMaxFromThreeNumer(a: Int, b: Int, c: Int): Int {
var max = Math.max(a, b)
max = Math.max(max, c)
return max
}
private fun getMinFromThreeNumer(a: Int, b: Int, c: Int): Int {
var min = Math.min(a, b)
min = Math.min(min, c)
return min
}
}