LeetCode152. 乘積最大子陣列
阿新 • • 發佈:2020-07-30
要求乘積最大的子陣列(子陣列一定都是連續的),可以暴力列舉子陣列起點和終點,求和。但是肯定超時。
如果用動態規劃,則只需要一遍掃描就可以得出結果。
可以用maxProduct[i]表示以i結尾的最大的子陣列乘積。
如果所有nums[i]都是正數,則maxProduct[i]就是max(nums[i], maxProduct[i - 1] * nums[i]),
也就是當前數和以i - 1結尾的最大子陣列乘積和當前數的乘積的較大值。
但是在這題裡,nums[i]有可能是負數,眾所周知負負得正,所以有可能前面某個子陣列的乘積非常的“負”且當前的nums[i]也是一個負數,
以至於之前的那個負的子陣列的積和nums[i]的乘積反而是最大的。
因此我們不僅需要一個maxProduct陣列記錄以當前位置i結尾的最大子陣列的積,還需要一個minProduct陣列記錄以當前位置i結尾的最小子陣列的積。
對於每一個maxProduct[i],它的值應該是nums[i], maxProduct[i - 1] * nums[i], minProduct[i - 1] * nums[i]三者中最大的,
對於每一個minProduct[i],它的值是三者中最小的。
我們只需要一遍掃描更新所有的maxProduct和minProduct。
最終答案就是maxProduct陣列中的最大值。
程式碼如下:
class Solution { public: int maxProduct(vector<int>& nums) { int size = nums.size(); vector<int> maxProduct(size), minProduct(size); maxProduct[0] = nums[0], minProduct[0] = nums[0]; for(int i = 1; i < size; ++i) { maxProduct[i] = max(nums[i], max(maxProduct[i - 1] * nums[i], minProduct[i - 1] * nums[i])); //這一行和下一行對調位置也行,只要更新了maxProduct和minProduct就好 minProduct[i] = min(nums[i], min(maxProduct[i - 1] * nums[i], minProduct[i - 1] * nums[i])); } return *max_element(maxProduct.begin(), maxProduct.end()); } };