打家劫舍3-遞歸到動(dòng)態(tài)規(guī)劃

337. 打家劫舍

在上次打劫完一條街道之后和一圈房屋后,小偷又發(fā)現(xiàn)了一個(gè)新的可行竊的地區(qū)厘熟。這個(gè)地區(qū)只有一個(gè)入口鸵贬,我們稱之為“根”。 除了“根”之外搁胆,每棟房子有且只有一個(gè)“父“房子與之相連。一番偵察之后邮绿,聰明的小偷意識(shí)到“這個(gè)地方的所有房屋的排列類似于一棵二叉樹”渠旁。 如果兩個(gè)直接相連的房子在同一天晚上被打劫,房屋將自動(dòng)報(bào)警船逮。
計(jì)算在不觸動(dòng)警報(bào)的情況下顾腊,小偷一晚能夠盜取的最高金額。
思路一:遞歸
1挖胃、偷該節(jié)點(diǎn)杂靶,則不偷左右節(jié)點(diǎn),偷左右節(jié)點(diǎn)的左右節(jié)點(diǎn)酱鸭。
int method1 = root.val + rob(root.left.left) + rob(root.left.right) + rob(root.right.left) + rob(root.right.right)
2吗垮、不偷該節(jié)點(diǎn),則偷該節(jié)點(diǎn)的左右節(jié)點(diǎn)凹髓。
int method2 = rob(root.left) + rob(root.right);
int result = Math.max(method1, method2);

class Solution {
public:
    int rob(TreeNode* root) { 
        if(!root)
            return 0;
        int s1=root->val;
        if(root->left)
        {
            s1+=rob(root->left->left)+rob(root->left->right);
        }
        if(root->right)
        {
            s1+=rob(root->right->left)+rob(root->right->right);
        }
        int s2=rob(root->left)+rob(root->right);
        return max(s1,s2);
    }
};

遞歸的時(shí)間復(fù)雜度O(2^n)烁登,空間復(fù)雜度O(n)。然而蔚舀,遞歸超時(shí)了饵沧,怎么辦呢?
思路二:動(dòng)態(tài)規(guī)劃
可以發(fā)現(xiàn)赌躺,在遞歸時(shí)捷泞,每求一次節(jié)點(diǎn)金額,需要重復(fù)訪問多次左右子樹寿谴,所以可以提前把偷過(guò)的子樹盜取的最大金額保存到一個(gè)哈希表锁右。從底向上保存偷或不偷該節(jié)點(diǎn)能達(dá)到的最大金額。
以上的算法對(duì)二叉樹做了一次后序遍歷讶泰,時(shí)間復(fù)雜度是 O(n)咏瑟;由于遞歸會(huì)使用到棧空間痪署,空間代價(jià)是 O(n)码泞,哈希表的空間代價(jià)也是 O(n),故空間復(fù)雜度也是 O(n)狼犯。

class Solution {
public:
    map<TreeNode*,int> m;
    int rob(TreeNode* root) { 
        if(!root)
            return 0;
        if(m[root]>0)
            return m[root];
        int s1=root->val;
        if(root->left)
        {
            s1+=rob(root->left->left)+rob(root->left->right);
        }
        if(root->right)
        {
            s1+=rob(root->right->left)+rob(root->right->right);
        }
        int s2=rob(root->left)+rob(root->right);
        m[root]=max(s1,s2);
        return m[root];
    }
};

思路三:優(yōu)化動(dòng)態(tài)規(guī)劃
上面的方法每次保存的值為最大值余寥,不確定是否偷該節(jié)點(diǎn)领铐,還要訪問孫子節(jié)點(diǎn)。為了簡(jiǎn)化宋舷,我們可以設(shè)計(jì)一個(gè)結(jié)構(gòu)绪撵,表示某個(gè)節(jié)點(diǎn)的f(偷)和 g (不偷)值,在每次遞歸返回的時(shí)候祝蝠,都把這個(gè)點(diǎn)對(duì)應(yīng)的f(偷)和 g (不偷)返回給上一級(jí)調(diào)用音诈,這樣可以省去哈希表的空間。將每個(gè)節(jié)點(diǎn)偷與不偷能達(dá)到的最大金額保存為一個(gè)pair绎狭。同樣细溅,也是分兩種情況:
1、偷該點(diǎn)
那么不能偷其左右節(jié)點(diǎn)儡嘶;
2喇聊、不偷該點(diǎn)
可以偷其左右節(jié)點(diǎn),也可以不偷其左右節(jié)點(diǎn)蹦狂,按照最大值誓篱。

class Solution {
public:
    int rob(TreeNode* root) { 
        if(!root)
            return 0;
        return max(dfs(root).first,dfs(root).second);
    }
    pair<int,int> dfs(TreeNode* root){
        pair<int,int> result={0,0};
        if(!root)
            return result;
        pair<int,int> Left=dfs(root->left);
        pair<int,int> Right=dfs(root->right);
        result.first=max(Left.first,Left.second)+max(Right.first,Right.second);
        result.second=root->val+Left.first+Right.first;
        return result;
    }
};

時(shí)間復(fù)雜度:O(n)。上文中已分析鸥咖。
空間復(fù)雜度:O(n)燕鸽。雖然優(yōu)化過(guò)的版本省去了哈希表的空間兄世,但是椞淅保空間的使用代價(jià)依舊是 O(n),故空間復(fù)雜度不變御滩。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末鸥拧,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子削解,更是在濱河造成了極大的恐慌富弦,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,406評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件氛驮,死亡現(xiàn)場(chǎng)離奇詭異腕柜,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)矫废,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門盏缤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人蓖扑,你說(shuō)我怎么就攤上這事唉铜。” “怎么了律杠?”我有些...
    開封第一講書人閱讀 163,711評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵潭流,是天一觀的道長(zhǎng)竞惋。 經(jīng)常有香客問我,道長(zhǎng)灰嫉,這世上最難降的妖魔是什么拆宛? 我笑而不...
    開封第一講書人閱讀 58,380評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮熬甫,結(jié)果婚禮上胰挑,老公的妹妹穿的比我還像新娘。我一直安慰自己椿肩,他們只是感情好瞻颂,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,432評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著郑象,像睡著了一般贡这。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上厂榛,一...
    開封第一講書人閱讀 51,301評(píng)論 1 301
  • 那天盖矫,我揣著相機(jī)與錄音,去河邊找鬼击奶。 笑死辈双,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的柜砾。 我是一名探鬼主播湃望,決...
    沈念sama閱讀 40,145評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼痰驱!你這毒婦竟也來(lái)了证芭?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,008評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤担映,失蹤者是張志新(化名)和其女友劉穎废士,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蝇完,經(jīng)...
    沈念sama閱讀 45,443評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡官硝,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,649評(píng)論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了短蜕。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片氢架。...
    茶點(diǎn)故事閱讀 39,795評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖忿危,靈堂內(nèi)的尸體忽然破棺而出达箍,到底是詐尸還是另有隱情,我是刑警寧澤铺厨,帶...
    沈念sama閱讀 35,501評(píng)論 5 345
  • 正文 年R本政府宣布缎玫,位于F島的核電站硬纤,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏赃磨。R本人自食惡果不足惜筝家,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,119評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望邻辉。 院中可真熱鬧溪王,春花似錦、人聲如沸值骇。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)吱瘩。三九已至道伟,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間使碾,已是汗流浹背蜜徽。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留票摇,地道東北人拘鞋。 一個(gè)月前我還...
    沈念sama閱讀 47,899評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像矢门,于是被迫代替她去往敵國(guó)和親盆色。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,724評(píng)論 2 354