LC 152. Maximum Product Subarray

2021-02-21 浩浩很無聊誒

今天沉迷愛的迫降,好在這道題不難,不然要做到深夜了。
題目雖然不難,但是是一道非常經典的dp,回顧總結一下對dp的了解

Maximum Product Subarray
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的思想其實和數學歸納法、RNN有很多類似的地方,出發點都是:怎麼從n -> n+1?怎麼利用前一個checkpoint的信息?
回到這道題本身,實現O(n)我的第一層思路是「每個點上紀錄一個以該點結尾的最大product」,然後用一個cur_max在迭代過程中不斷更新最後輸出
往第二層思路入點是n+1點上的最大product,是怎麼從n點計算過來的?需要哪些信息?於是想到如果n+1處是正數就直接乘,如果是負,那麼應當是「n處的負「最大絕對值」乘積」,那麼很自然,一開始需要儲存的是「以該點結尾的正最大product和負最大product,最大的含義為絕對值」


一些修補和細節增添之後就有了如下非常淺顯的代碼。在coding這邊,我的理解還算很淺,有兩句話我是一直當作座右銘:

其一,talk is cheap - show me the code。有時候話說的再多不如直接代碼直觀。其二,premature optimization is the root of all evil。尤其是做網申題,思路要清晰,pseudo code轉化成代碼的過程中除非有bug儘量不優化,忍住優化的欲望記下筆記跑通之後再優化,不然有可能前後思路或者某個變量的使用不一致。

下面這個代碼我是一遍跑通的沒有bug,看著醜但是思路還可以,只有一個corner case在於數組只有一個負數的時候,其實和我對於兩個輔助容器的定義有問題(歸0的地方),所以我單獨列出來了

class Solution {
public:
    int maxProduct(vector<int>& nums) {
        if (nums.size() == 0) return 0;
        if (nums.size() == 1) return nums[0];
        int n = nums.size();
        int pos[n];
        int neg[n];

        pos[0] = nums[0] > 0 ? nums[0] : 0;
        neg[0] = nums[0] < 0 ? nums[0] : 0;


        int cur_max = pos[0];

        for (int i = 1; i < n; i++){
            if (nums[i] > 0){
                if(pos[i-1] > 0) pos[i] = pos[i-1] * nums[i];
                else pos[i] = nums[i];

                if(neg[i-1] < 0) neg[i] = neg[i-1] * nums[i];
                else neg[i] = 0;
            }

            else if (nums[i] == 0){
                pos[i] = 0;
                neg[i] = 0;
            }

            else{//nums[i] < 0
                if (neg[i-1] < 0) pos[i] = neg[i-1] * nums[i];
                else pos[i] = 0;

                if (pos[i-1] > 0) neg[i] = pos[i-1] * nums[i];
                else neg[i] = nums[i];
            }

            cur_max = pos[i] > cur_max ? pos[i] : cur_max;
            //cout << i << '|' << pos[i] << '|' << neg[i] << endl;
        }

        return cur_max;
    }
};

優化

很明顯,pos[i]和neg[i]只用到了pos[i-1]和neg[i-1],沒必要用容器,直接用變量,實現O(1)空間佔用

可以直接維護max和min。。。fmax[i] = max(fmax[i-1] * nums[i], fmin[i-1] * nums[i], nums[i]),這個思路就顯得我很菜

class Solution {
public:
    int maxProduct(vector<int>& nums) {
        int maxF = nums[0], minF = nums[0], ans = nums[0];
        for (int i = 1; i < nums.size(); ++i) {
            int mx = maxF, mn = minF;
            maxF = max(mx * nums[i], max(nums[i], mn * nums[i]));
            minF = min(mn * nums[i], min(nums[i], mx * nums[i]));
            ans = max(maxF, ans);
        }
        return ans;
    }
};
//作者:LeetCode-Solution
//連結:https://leetcode-cn.com/problems/maximum-product-subarray/solution/cheng-ji-zui-da-zi-shu-zu-by-leetcode-solution/
//來源:力扣(LeetCode)
//著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。

相關焦點

  • sumproduct函數用法全匯總,輕鬆玩轉綜合權重排名
    今天我們來學習一個經典的sumproduct函數。讓大家在單條件計算與多條件計算、綜合權重排名、及多維度區域計算等場景變得更加簡單。函數詳解:SUMPRODUCT(array1,array2,array3, ...)
  • SUMPRODUCT函數三大經典案例
    由此可知,這是一道單條件計數問題,通常我們都是用countif函數,那如何運用Sumproduct單條件計數呢,如下所示:由此可知,這是一道單條件求和問題,通常我們都是用sumif函數,那如何運用Sumproduct單條件求和呢,如下所示:
  • Sumproduct_條件求和(多_可且可或)_Excel
    我們的A系列已經結束,錯過A系列沒有關係,A系列基本都是講技巧,A系列全套示例文件(196MB)已經全部開放,下載收藏就行,做到了解即可。Sumproduct_條件求和(多_可且可或)多條件求和函數類區函數格式(官方)函數格式(中文)Sumproduct數學SUMPRODUCT(array1,array2,array3,…)SUMPRODUCT(數組1,數組2,數組3,…)今天不上動圖Sumproduct_條件求和(多_純且)注意:如果不是引用單元格
  • 字母圈dom和sub
    字母圈dom和sub如何慢慢發展及相處呢?那麼,今天就來給大家好好想一下字母圈dom和sub的意思,以及字母圈dom和sub如何長期維持關係及注意點,小灰灰們可以一起來學習哦~字母圈dom和sub是什麼意思:Dom全稱為:dominance 翻譯過來就是支配Sub全稱為:submission 翻譯過來為臣服這是DB5M中較大的一個群體,及DS群體,但是網上關於dom和sub
  • 進一步了解S與M、Dom與Sub
    dom和sub接觸以後,如果決定建立長期關係,會有一個計劃。一般有觀察(早期了解),開始(通過某些手段讓sub信服,服從),調教(針對sub的偏差執行調整計劃),回歸(解開束縛手段,讓sub恢復無礙的正常生活)。可能大部分人都不知道這三個步驟,絕大多數的調教還局限在第一階段。很少人能進入第二階段。真正達到第三階段並結束的,就更罕見了。
  • 8種sumproduct函數的使用方法,除了強大,我不知道說什麼了
    今天要給大家介紹下Excel中的「萬能公式」sumproduct函數,為什麼說他是萬能的呢,因為它能做的事情是實在多了,廢話不多說我們開始把sumproduct函數以及參數sumproduct函數:返回相應的數組或區域乘積的和第一參數:Array1第二參數:array2第三參數:array3,…….最多
  • 兩大經典案例帶你玩轉Excel必會函數之SUMPRODUCT函數
    小雅建議夥伴結合英語來理解SUMPRODUCT函數:sum是和,product是積
  • 強大的SUMPRODUCT函數,你會用嗎?
    =SUMPRODUCT(array1,array2,array3, ...),array為數組或區域。數組參數必須具有相同的維數,否則,函數 SUMPRODUCT 將返回錯誤值 #VALUE!一般情況下,使用SUMPRODUCT()函數可以返回相應的數組或區域乘積的和。