8.14 dp maximalRec & bestTimeToBuy & InterleavingStr

- to do

- before 13.4] Maximal Square

mark: improve using rotating array

    int maximalSquare(vector<vector<char>>& matrix) {
        if (matrix.empty() || matrix[0].empty()) return 0;
        int m = matrix.size(), n = matrix[0].size(); 
        // dp : maxSide[i][j] stores maximalSquare's side length who uses matrix[i][j] as rightMost corner
        vector<vector<int>> maxSide(m, vector<int>(n, 0));
        int ret = 0;
        for (int i=0; i<m; ++i) {
            maxSide[i][0] = matrix[i][0]-'0';
            ret = max(ret, maxSide[i][0]);
        }
        for (int j=0; j<n; ++j) {
            maxSide[0][j] = matrix[0][j]-'0';
            ret = max(ret, maxSide[0][j]);
        }
        for (int i=1; i<m; ++i) {
            for (int j=1; j<n; ++j) {
                if (matrix[i][j]!='0')  {
                    int m1 = maxSide[i][j-1], m2 = maxSide[i-1][j], minm = min(m1, m2);
                    maxSide[i][j] = minm + (matrix[i-minm][j-minm]-'0');
                    ret = max(ret, maxSide[i][j]);
                }
            }
        }
        return ret*ret;
    }

- again Largest Rectangle in Histogram

- 1) 改进的暴力 O(n)?

  • 最原始的暴力是从左往右遍历,当前ith whole bar为左界限,向右延伸找第一个矮于自己的; 算出面积。O(n^2)
  • 或者另一种想法,最大矩形必然包含了某一个立柱的全部。所以遍历是向左右延伸,算用了当前立柱的最大面积。(所以当前立柱是rect内最低高度)
    • 所以每一步想要知道lefti of 向左延伸遇到的第一个比自己矮的立柱,以及righti同理。所以area = heights[i] * (righti-lefti-1)。 这里又有两种办法
      1. dp 两遍遍历构建leftIndex[], rightIndex[]
      2. 用非递减stack来找lefti/righti
        先说stack的办法:
  1. 考虑非递减的array【1,4,5,5,7,9】,如果算用了当前立柱的最大面积,很简单只需要从右往左遍历,记住incremental的宽度n-i,乘以height[i]得到面积。(虽然在重复值情况中,【n-2】的5不会得到最大值,但是最左边的重复值会保证捕捉最大值)
  2. 如果在1的基础上加上一个违反规律更小的6 => array【1,4,5,5,7,9,6】



    ===========我是启动画面(xia)感(che)的分割线==============

顺序的大人的看到了小矮红i的加入,之前的简单算法hold不住了,暂停下遍历来观察下:
发现在小矮红线以上的那些高柱其实找到了righti就是i,换而言之小矮成了高柱们一辈子的短板限制,sad;而小矮呢,它的lefti并不关心高柱们有多高多厉害,而是向左第一个比小矮还矮的柱子2hhh。
既然互不关心一拍即合,那么高柱们就退场了,但别漏了当maxArea的可能性啊,所以退场前算一下Area:height[self] * (i-lefti-1) where lefti = s.empty()? i : s.top().

退场结束。
终于又回到非递增的规则世界~可是退场的高柱会影响未来的面积记录突破吗?小矮说 不会的,即使高柱在,未来我右边的每个柱子往左延伸都要经过我这一关,别忘了我是他们的短板。
那好,别忘了所有柱子都要算面积,元素都是算了面积再被pop,意思是stack最后要清空。当然可以加一个while not empty{loop},或者巧妙的
resume遍历

  • 所以这道题和Maximal Rect相通之处就是可以把平面看做大矩阵,条形看做1,非条形看做0,寻找最大全1矩阵。
  • reference
public:
// 暴力
    int largestRectangleArea(vector<int>& heights) {
        if (heights.empty()) return 0;
        int n = heights.size();
        vector<int> h(n+2, -1);
        // left[i] gives the index of farthest reachable bar on the LHS
        vector<int> left(n+1, -1);
        vector<int> right(n+2, -1);
        //往左找第一个比自己矮的
        for (int i=1; i<=n; ++i) {
            int k = i;
            //比自己高就继续找
            while (h[i] <= h[k-1]) k = left[k-1];
            left[i] = k;
        }
        for (int i=n; i>0; --i) {
            int k = i;
            //比自己高就继续找
            while (h[i] <= h[k+1]) k = right[k+1];
            right[i] = k; 
        }
        int ret = 0;
        for (int i=1; i<=n; ++i) {
            ret = max(ret, h[i]*(right[i]-left[i]+1));
        }
        return ret;
    }

- 2) using stack

    int largestRectangleArea(vector<int>& heights) {
        int ret = 0, n = heights.size();
        stack<int> s;
        // want to calculate maxarea using the whole heights[i]
        // meaning: extend farthest to left, find first bar < heights[i]; same to right
        int i=0; 
        while (i<n) {
            if (s.empty() || heights[i]>=heights[s.top()]) {
                s.push(i++);
            } else {
                // calculate area of bar w/ heights[tp] as height
                int tp = s.top();
                s.pop();
                int width = s.empty()? i : i-s.top()-1;
                ret = max(ret, width*heights[tp]);
            }
        }
        while (!s.empty()) {
            // calculate area of bar w/ heights[tp] as height
            int tp = s.top();
            s.pop();
            int width = s.empty()? i : i-s.top()-1;
            ret = max(ret, width*heights[tp]);            
        }
        return ret;
    }

13.5] Best Time to Buy and Sell Stock III

lalala
开始忘记stockI解dp存的是当天卖会得到的收入,而非当前最佳收入。

    int maxProfit(vector<int>& prices) {
        int n = prices.size();
        if (n<2) return 0;
        // build dp1: dp1[i] gives maxProfit so far of period [0-i]
        int minSoFar = prices[0], maxP = 0;
        vector<int> dp1(n, -1);
        for (int i=0; i<n; ++i) {
            minSoFar = min(minSoFar, prices[i]);
            maxP = max(maxP, prices[i] - minSoFar);
            dp1[i] = maxP;
        }
        // build dp2: dp2[i] gives maxProfit so far of period [i-(n-1)]
        int maxSoFar = prices[n-1];
        maxP = 0;
        vector<int> dp2(n, -1);
        for (int i=n-1; i>=0; --i) {
            maxSoFar = max(maxSoFar, prices[i]);
            maxP = max(maxP, maxSoFar - prices[i]);
            dp2[i] =maxP;
        }     
        // dp2[n] = 0
        dp2.push_back(0);
        // build dp3: 
        int maxRet = INT_MIN;
        for (int k=0; k<n; ++k) {
            maxRet = max(maxRet, dp1[k] + dp2[k+1]);
        }
        return maxRet;
    }

- naive recursive method

    bool isInterleave(string s1, string s2, string s3) {
        if (s3.size() != s1.size() + s2.size()) return false;
        if (s2.empty()) return s1.compare(s3)==0;
        if (s1.empty()) return s2.compare(s3)==0;
        if (s1[0]!=s3[0] && s2[0]!=s3[0]) return false;

        bool ret = false;
        if (s1[0]==s3[0]) ret = ret || isInterleave( s1.substr(1, s1.size()-1), s2, s3.substr(1, s3.size()-1) );
        if (s2[0]==s3[0]) ret = ret || isInterleave( s1, s2.substr(1, s2.size()-1), s3.substr(1, s3.size()-1) );
        return ret;
    }

- better dp

Make sure understand what the memo structure holds and where the bound is. Follow the equation at all time. Bug when I wasn't clear what the boundry means and another bug see comment below.

    bool isInterleave(string s1, string s2, string s3) {
       if (s1.size()+s2.size() != s3.size()) return false;
       if (s3.empty()) return true;
       int m = s1.size(), n = s2.size(), l = s3.size();
       
       vector<vector<bool>> dp(m+1, vector<bool>(n+1, false));
       dp[m][n] = true;
       for (int i=m-1; i>=0; --i) dp[i][n] = dp[i+1][n] && s1[i]==s3[i+n];
       for (int j=n-1; j>=0; --j) dp[m][j] = dp[m][j+1] && s2[j]==s3[m+j];
       
       for (int i=m-1; i>=0; --i) {
           for (int j=n-1; j>=0; --j) {
               int k = i+j;
               if (s3[k]==s1[i] || s3[k]==s2[j]) {
                   dp[i][j] = (s3[k]==s1[i] && dp[i+1][j]) ||
                              (s3[k]==s2[j] && dp[i][j+1]);
               }
           }
       }
       return dp[0][0];
    }

- optimize using rotating array

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,098评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,213评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,960评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,519评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,512评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,533评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,914评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,804评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,563评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,644评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,350评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,933评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,908评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,146评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,847评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,361评论 2 342

推荐阅读更多精彩内容