給定一個(gè)整數(shù)數(shù)組 nums ,找出一個(gè)序列中乘積最大的連續(xù)子序列(該序列至少包含一個(gè)數(shù))垄分。
示例 1:
輸入: [2,3,-2,4]
輸出: 6
解釋: 子數(shù)組 [2,3] 有最大乘積 6宛篇。
示例 2:輸入: [-2,0,-1]
輸出: 0
解釋: 結(jié)果不能為 2, 因?yàn)?[-2,-1] 不是子數(shù)組。
來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/maximum-product-subarray
著作權(quán)歸領(lǐng)扣網(wǎng)絡(luò)所有锋喜。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系官方授權(quán)些己,非商業(yè)轉(zhuǎn)載請(qǐng)注明出處。
動(dòng)態(tài)規(guī)劃
- 定義狀態(tài):
fmax(i) = 從坐標(biāo)0(可以不包括)到坐標(biāo)i(必須包括坐標(biāo)i)嘿般,乘積最大的連續(xù)子序列
fmin(i) = 從坐標(biāo)0(可以不包括)到坐標(biāo)i(必須包括坐標(biāo)i)段标,乘積最小的連續(xù)子序列 - 狀態(tài)轉(zhuǎn)移方程:
因?yàn)榇嬖?的情況,所以當(dāng)fmax(i-1)=0炉奴,則num[i]很可能就是最大或者最小值
存最小值是因?yàn)楸婆樱?dāng)負(fù)的值乘以負(fù)數(shù)就變最大值了
fmax(i) = max(fmax(i-1) * num[i], fmin(i-1) * num[i], num[i])
fmin(i) = min(fmax(i-1) * num[i], fmin(i-1) * num[i], num[i])
class Solution {
/**
* 動(dòng)態(tài)規(guī)劃
*
* @param nums
* @return
*/
public int maxProduct(int[] nums) {
// 初始化index=0的情況
int beforeMax, beforeMin, max;
max = beforeMax = beforeMin = nums[0];
for (int i = 1; i < nums.length; i++) {
// 獲取到包括當(dāng)前index=i元素時(shí)的最大連續(xù)子序列乘積
int tmpBeforeMax = Math.max(Math.max(beforeMax * nums[i], beforeMin * nums[i]), nums[i]);
// 獲取到包括當(dāng)前index=i元素時(shí)的最小連續(xù)子序列乘積
int tmpBeforeMin = Math.min(Math.min(beforeMax * nums[i], beforeMin * nums[i]), nums[i]);
beforeMax = tmpBeforeMax;
beforeMin = tmpBeforeMin;
// 記錄過程中產(chǎn)生的最大值
if (beforeMax > max) {
max = beforeMax;
}
}
return max;
}
public static void main(String[] args) {
int[] nums = {-4, -3, -2};
int maxProduct = new Solution().maxProduct(nums);
System.out.println(maxProduct);
}
}