8.13 dp: triangle & maximumSubArr & palindromePartitionII

to do

13.1] Triangle

一开始理解错了,adjacent是说下一行可以保持index或是index+1

- naive method

n*n space and build from top of triangle to bottom

    int minimumTotal(vector<vector<int>>& triangle) {
        if (triangle.empty()) return 0;
        int lastLineLen = triangle[triangle.size()-1].size();

        vector<vector<int>> minSum (triangle.size(), vector<int>(lastLineLen, INT_MAX) );
        minSum[0][0] = triangle[0][0];
        for (int row=1; row<triangle.size(); ++row) {
            for (int index=0; index<triangle[row].size(); ++index) {
                for (int lastRowIndex = index-1; lastRowIndex <index+1; ++lastRowIndex) {
                    if (lastRowIndex<0 || lastRowIndex>=triangle[row-1].size()) continue;
                    minSum[row][index] = min(minSum[row][index], minSum[row-1][lastRowIndex]+triangle[row][index]);
                }
                // cout<<"minSum["<<row<<"]["<<index<<"]="<<minSum[row][index]<<endl;
            }
        }
        return *min_element(minSum[minSum.size()-1].begin(), minSum[minSum.size()-1].end());
    }

- Better version.

Use O(n) space and build from bottom to top in avoidance of index out of bound

    int minimumTotal(vector<vector<int>>& triangle) {
        if (triangle.empty()) return 0;
        vector<int> lowerRow = triangle[triangle.size()-1];
        for (int row=triangle.size()-2; row>=0; --row) {
            vector<int> higherRow(triangle[row].size(), -1);
            for (int i=0; i<higherRow.size(); ++i) {
                higherRow[i] = triangle[row][i] + min(lowerRow[i], lowerRow[i+1]);
            }
            lowerRow = higherRow;
        }
        return lowerRow[0];
    }

13.2] maximum-subarray

- If exists no negative numbers, simply keep adding to find the maximum.

    int maxSubArray(vector<int>& nums) {
        int maxSoFar = 0, maxEndingHere = 0; 
        for (int i=0; i<nums.size(); ++i) {
            maxEndingHere += nums[0];
            maxSoFar = maxEndingHere<0? 0 : max(maxSoFar, maxEndingHere);
        }
        return maxSoFar;
    }

- add the negative cases. It means we'll make comprimise when considering if we should add the last new number.

  • Assume we've solved subproblems where input string length <=n and stored answers in array maxSumArr: maxSumArr[i] gives the maximum sum of subarrary ending with s[i].
  • Now consider incremental step where string s of length n+1
    • case 1: add s[n+1] to maxSumArr[n]. Only meaningful if maxSumArry[n]>=0
    • case 2: Else if maxSumArry[n]<0, start newSubArray with s[n+1]
    • => maxSumArry[n+1] = max(maxSumArry[n]+s[n+1], s[n+1]);
    • base case: maxSumArry[0] = s[0]
    • what to return?
    int maxSubArray(vector<int>& nums) {
        vector<int> maxSumArr = {nums[0]};
        for (int i=1; i<nums.size(); ++i) {
            maxSumArr.push_back( max(maxSumArr[i-1]+nums[i], nums[i]) );
        }
        return *max_element(maxSumArr.begin(), maxSumArr.end());
    }

mark redo w/ divide and conquer

优化的暴破法只要O(n)是的只要O(n)你没有看错走过路过不要错过

13.3] Palindrome Partitioning II

redo !!!!

dp for isPalin table,
dp for partitioning string

    bool isPalindrome(string s) {
        for (int l=0, r=s.size()-1; l<r; ++l, --r) {
            if (s[l] != s[r]) return false;
        }
        return true;
    }
    
    int minCut(string s) {
        if (s.size()<2) return 0;
        vector<vector<bool>> isPalin(s.size(), vector<bool>(s.size(), true));
        // build isPalin lookup table
        for (int i=s.size()-1; i>=0; --i) {
            for (int j=i; j<s.size(); ++j) 
                isPalin[i][j] = i==j? true : isPalin[i+1][j-1] && s[i]==s[j]; // init to true took care of basecases
        }
        // for (auto& v: isPalin) {
        //     for (int i=0; i<v.size(); ++i) cout<<" "<<i<<":"<<v[i];
        //     cout<<endl;
        // }
        // build dp array
        vector<int> minCut(s.size(), INT_MAX);
        for (int i=0; i<s.size(); ++i) {
            // find a pivot to cut into a palindrome and a solved sub-problem
            for (int k=0; k<=i; ++k) {
                if (isPalin[k][i]) {
                    if (k==0) {
                        minCut[i] = 0;
                        break;
                    }
                    minCut[i] = min(minCut[i],  minCut[k-1] + 1);
                    // cout<<"curr"<<curr<<"=minCut["<<k<<"-1] = "<<minCut[k-1]<<" minCut["<<i<<"]"<<minCut[i]<<endl;
                }
            }
        }
        return minCut[s.size()-1];
    }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 161,192评论 4 369
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 68,186评论 1 303
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 110,844评论 0 252
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,471评论 0 217
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,876评论 3 294
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,891评论 1 224
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,068评论 2 317
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,791评论 0 205
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,539评论 1 249
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,772评论 2 253
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,250评论 1 265
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,577评论 3 260
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,244评论 3 241
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,146评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,949评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,995评论 2 285
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,812评论 2 276

推荐阅读更多精彩内容

  • 背景 一年多以前我在知乎上答了有关LeetCode的问题, 分享了一些自己做题目的经验。 张土汪:刷leetcod...
    土汪阅读 12,663评论 0 33
  • **2014真题Directions:Read the following text. Choose the be...
    又是夜半惊坐起阅读 8,604评论 0 23
  • Charles❤️的情書。歌吟有梦,筑梦蓝天。有梦才会有追求,正是因为少年时代的一个梦想,那个行走雨巷里的丁香一样...
    courtlike阅读 256评论 0 0
  • 6点23分 地震前 老婆把我的被子掀开,整个人轻轻的压在我的身上,每次我们做完爱的第二天早晨她都会这样把我压醒。 ...
    6fe78c0c9474阅读 204评论 2 1
  • 昨晚一晚都在梦中行走[偷笑] 感谢教练的分享,让我想起了很多美好的回忆:深夜穿越森林;深夜在大海边跟大海对话,拥抱...
    吴陈芬Grace阅读 321评论 0 2