LeetCode動(dòng)態(tài)規(guī)劃

198.打家劫舍

題目描述:你是一個(gè)專業(yè)的小偷析苫,計(jì)劃偷竊沿街的房屋衩侥。每間房內(nèi)都藏有一定的現(xiàn)金,影響你偷竊的唯一制約因素就是相鄰的房屋裝有相互連通的防盜系統(tǒng)茫死,如果兩間相鄰的房屋在同一晚上被小偷闖入,系統(tǒng)會(huì)自動(dòng)報(bào)警峦萎。
給定一個(gè)代表每個(gè)房屋存放金額的非負(fù)整數(shù)數(shù)組屡久,計(jì)算你 不觸動(dòng)警報(bào)裝置的情況下 骨杂,一夜之內(nèi)能夠偷竊到的最高金額。

思路分析:

  • 動(dòng)態(tài)規(guī)劃方程:dp[n] = MAX( dp[n-1], dp[n-2] + num )
  • 由于不可以在相鄰的房屋闖入搓蚪,所以在當(dāng)前位置 n 房屋可盜竊的最大值丁鹉,要么就是 n-1 - 房屋可盜竊的最大值,要么就是 n-2 房屋可盜竊的最大值加上當(dāng)前房屋的值揣钦,二者之間取最大值
  • 舉例來說:1 號(hào)房間可盜竊最大值為 33 即為 dp[1]=3,2 號(hào)房間可盜竊最大值為 44 即為 dp[2]=4冯凹,3 號(hào)房間自身的值為 22 即為 num=2,那么 dp[3] = MAX( dp[2], dp[1] + num ) = MAX(4, 3+2) = 5宇姚,3 號(hào)房間可盜竊最大值為 5
  • 時(shí)間復(fù)雜度:O(n)O(n),nn 為數(shù)組長度
var rob = function(nums) {
    let len = nums.length;
    if (len === 0) return 0;
    let dp = [];
    dp[0] = nums[0];
    dp[1] = Math.max(nums[0],nums[1]);
    for (let i = 2; i < len; i++) {
        dp[i] = Math.max(dp[i-1],dp[i-2]+nums[i]);
    }
    return dp[len-1];
};

213.打家劫舍II

題目描述:你是一個(gè)專業(yè)的小偷阱持,計(jì)劃偷竊沿街的房屋,每間房內(nèi)都藏有一定的現(xiàn)金衷咽。這個(gè)地方所有的房屋都圍成一圈,這意味著第一個(gè)房屋和最后一個(gè)房屋是緊挨著的蒜绽。同時(shí),相鄰的房屋裝有相互連通的防盜系統(tǒng)躲雅,如果兩間相鄰的房屋在同一晚上被小偷闖入,系統(tǒng)會(huì)自動(dòng)報(bào)警此蜈。
給定一個(gè)代表每個(gè)房屋存放金額的非負(fù)整數(shù)數(shù)組,計(jì)算你在不觸動(dòng)警報(bào)裝置的情況下裆赵,能夠偷竊到的最高金額。
思路分析:
本題為上一題的加強(qiáng)版战授,可以分為兩種情況:

  • 偷第一家页藻,則不投最后一家
  • 不偷第一家植兰,則偷最后一家
    將兩張情況的切片數(shù)組代入到上一題的函數(shù)里,求得兩個(gè)結(jié)果取最大值即可楣导。
var rob = function(nums) {
    if (nums.length === 0) return 0;
    if (nums.length === 1) return nums[0];
    return Math.max(DP(nums.slice(1)), DP(nums.slice(0,nums.length-1)));
    //198題打家劫舍的函數(shù)
    function DP(nums) {
        let len = nums.length;
        if (len === 0) return 0;
        let dp = [];
        dp[0] = nums[0];
        dp[1] = Math.max(nums[0],nums[1]);
        for (let i = 2; i < len; i++) {
            dp[i] = Math.max(dp[i-1],dp[i-2]+nums[i]);
        }
        return dp[len-1];
    }
};

337.打家劫舍III

題目描述:在上次打劫完一條街道之后和一圈房屋后,小偷又發(fā)現(xiàn)了一個(gè)新的可行竊的地區(qū)噩凹。這個(gè)地區(qū)只有一個(gè)入口,我們稱之為“根”驮宴。 除了“根”之外呕缭,每棟房子有且只有一個(gè)“父“房子與之相連堵泽。一番偵察之后迎罗,聰明的小偷意識(shí)到“這個(gè)地方的所有房屋的排列類似于一棵二叉樹”。 如果兩個(gè)直接相連的房子在同一天晚上被打劫佳谦,房屋將自動(dòng)報(bào)警。
計(jì)算在不觸動(dòng)警報(bào)的情況下钻蔑,小偷一晚能夠盜取的最高金額。
思路分析:
打不打劫根節(jié)點(diǎn)咪笑,會(huì)影響打劫一棵樹的收益:

  • 打劫根節(jié)點(diǎn)娄涩,則不能打劫左右子節(jié)點(diǎn)窗怒,但是能打劫左右子節(jié)點(diǎn)的四個(gè)子樹扬虚。
  • 不打劫根節(jié)點(diǎn),則能打劫左子節(jié)點(diǎn)和右子節(jié)點(diǎn)辜昵,收益是打劫左右子樹的收益之和。
    因此可以遞歸計(jì)算堪置。
const rob = (root) => { // 打劫以root為根節(jié)點(diǎn)的子樹的最大收益
  if (root == null) return 0;
  // 打劫包括根節(jié)點(diǎn)的收益躬存,保底是root.val
  let robIncludeRoot = root.val; 
  if (root.left) {
    robIncludeRoot += rob(root.left.left) + rob(root.left.right);
  }
  if (root.right) {
    robIncludeRoot += rob(root.right.left) + rob(root.right.right);
  }
  // 打劫不包括根節(jié)點(diǎn)的收益
  const robExcludeRoot = rob(root.left) + rob(root.right); 
  // 二者取其大
  return Math.max(robIncludeRoot, robExcludeRoot); 
};

但是注意舀锨,我們計(jì)算了 root 的四個(gè)孫子子樹,又計(jì)算了 root 的左右子樹盾剩,而后者會(huì)把 root 的孫子子樹重復(fù)計(jì)算一遍。我們把計(jì)算過的結(jié)果存到 map彪腔。下次遇到相同的子問題時(shí)直接拿過來用,不用做重復(fù)的遞歸。這就是動(dòng)態(tài)規(guī)劃——記憶化遞歸恭垦。

const rob = (root) => {
  const memo = new Map();
  return helper(root);

  const helper = (root) => {
    if (root == null) return 0;
    // memo中有緩存的結(jié)果,直接返回它
    if (memo.has(root)) return memo.get(root);

    let robIncludeRoot = root.val;
    if (root.left) {
      robIncludeRoot += helper(root.left.left) + helper(root.left.right);
    }
    if (root.right) {
      robIncludeRoot += helper(root.right.left) + helper(root.right.right);
    }

    const robExcludeRoot = helper(root.left) + helper(root.right);

    const res = Math.max(robIncludeRoot, robExcludeRoot);
    // 保存當(dāng)前子樹的計(jì)算結(jié)果
    memo.set(root, res);
    return res;
  };
};

連續(xù)子數(shù)組的最大值

輸入一個(gè)整型數(shù)組番挺,數(shù)組中的一個(gè)或連續(xù)多個(gè)整數(shù)組成一個(gè)子數(shù)組。求所有子數(shù)組的和的最大值襟衰。

動(dòng)態(tài)規(guī)劃
var maxSubArray = function(nums) {
    let temp = nums[0];
    let max = nums[0];
    for (let i = 1; i < nums.length; i++) {
        if (temp > 0) {
            temp = temp + nums[i];
        } else {
            temp = nums[i];
        }
        max = Math.max(temp, max);
    }
    return max;
};
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市瀑晒,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌苔悦,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,734評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件玖详,死亡現(xiàn)場離奇詭異勤讽,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)脚牍,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,931評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來莫矗,“玉大人砂缩,你說我怎么就攤上這事三娩♀职牛” “怎么了雀监?”我有些...
    開封第一講書人閱讀 164,133評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長好乐。 經(jīng)常有香客問我,道長蔚万,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,532評(píng)論 1 293
  • 正文 為了忘掉前任反璃,我火速辦了婚禮,結(jié)果婚禮上淮蜈,老公的妹妹穿的比我還像新娘。我一直安慰自己梧田,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,585評(píng)論 6 392
  • 文/花漫 我一把揭開白布裁眯。 她就那樣靜靜地躺著闺魏,像睡著了一般未状。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上析桥,一...
    開封第一講書人閱讀 51,462評(píng)論 1 302
  • 那天泡仗,我揣著相機(jī)與錄音,去河邊找鬼娩怎。 笑死,一個(gè)胖子當(dāng)著我的面吹牛截亦,可吹牛的內(nèi)容都是我干的爬泥。 我是一名探鬼主播,決...
    沈念sama閱讀 40,262評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼踩官,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼!你這毒婦竟也來了蔗牡?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,153評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤辩越,失蹤者是張志新(化名)和其女友劉穎信粮,沒想到半個(gè)月后黔攒,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,587評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡亏钩,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,792評(píng)論 3 336
  • 正文 我和宋清朗相戀三年欺旧,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了蛤签。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,919評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡称龙,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出鲫尊,到底是詐尸還是另有隱情,我是刑警寧澤沦偎,帶...
    沈念sama閱讀 35,635評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站豪嚎,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏侈询。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,237評(píng)論 3 329
  • 文/蒙蒙 一扔字、第九天 我趴在偏房一處隱蔽的房頂上張望温技。 院中可真熱鬧扭粱,春花似錦、人聲如沸焊刹。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,855評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽俩滥。三九已至贺奠,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間儡率,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,983評(píng)論 1 269
  • 我被黑心中介騙來泰國打工儿普, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人眉孩。 一個(gè)月前我還...
    沈念sama閱讀 48,048評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像浪汪,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子死遭,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,864評(píng)論 2 354