337. House Robber III

The thief has found himself a new place for his thievery again. There is only one entrance to this area, called the "root." Besides the root, each house has one and only one parent house. After a tour, the smart thief realized that "all houses in this place forms a binary tree". It will automatically contact the police if two directly-linked houses were broken into on the same night.

Determine the maximum amount of money the thief can rob tonight without alerting the police.

Example 1:

     3
    / \
   2   3
    \   \ 
     3   1

Maximum amount of money the thief can rob = 3 + 3 + 1 = 7.

Example 2:

     3
    / \
   4   5
  / \   \ 
 1   3   1

Maximum amount of money the thief can rob = 4 + 5 = 9.

一刷
題解:

方法1:問題可以分解為, 取 root.val + rob(root.left.left) + rob(root.left.right) + rob(root.right.left) + rob(root.right.right) 和rob(root.left) + rob(root.right)的較大值谭溉。
由于動態(tài)規(guī)劃的思想润梯,這樣明顯會重復(fù)計算很多子問題。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    public int rob(TreeNode root) {
       if(root == null) return 0;
        int val = 0;
        
        if(root.left!=null)
            val += rob(root.left.left) + rob(root.left.right);
        
        if(root.right !=null)
            val += rob(root.right.left) + rob(root.right.right);
        
        return Math.max(val+root.val, rob(root.left) + rob(root.right));
    }
}

方法2:
由于方法1有很多重復(fù)計算,于是考慮用map存儲中間值

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    public int rob(TreeNode root) {
       return robSub(root, new HashMap<>());
    }
    
    private int robSub(TreeNode root, Map<TreeNode, Integer> map){
        if(root == null) return 0;
        if(map.containsKey(root)) return map.get(root);
        int val = 0;
        if(root.left!=null){
            val+= robSub(root.left.left, map) + robSub(root.left.right, map);
        }
        if(root.right!=null) val+= robSub(root.right.left, map) + robSub(root.right.right, map);
        
        val = Math.max(root.val + val, robSub(root.left, map)+robSub(root.right, map));
        map.put(root, val);
        return val;
    }
}

方法3:
不需要用map存儲這么多中間值实蔽,只需要存儲res[0]表示決定不偷當前root的值對應(yīng)的結(jié)果上炎,res[1]表示偷。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    public int rob(TreeNode root) {
        int[] res = robSub(root);
        return Math.max(res[0], res[1]);
    }
    
    private int[] robSub(TreeNode root){
        if(root == null) return new int[2];
        
        int[] left = robSub(root.left);
        int[] right = robSub(root.right);
        int[] res = new int[2];
        
        res[0] = Math.max(left[0], left[1]) + Math.max(right[0], right[1]);
        res[1] = root.val + left[0] + right[0];
        return res;
    }
}

二刷蕊程, 自底向上(用遞歸實現(xiàn))椒袍,動態(tài)規(guī)劃的思路。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    public int rob(TreeNode root) {
        int [] res = robdual(root);
        return Math.max(res[0], res[1]);
    }
    
    
    private int[] robdual(TreeNode root){
        int[] res = new int[2];
        if(root == null) return res;
        if(root.left == null && root.right == null){
            res[1] = root.val;
            return res;
        }
        int[] left = robdual(root.left);
        int[] right = robdual(root.right);
        //not rob root
        res[0] = Math.max(left[0], left[1]) + Math.max(right[0], right[1]);
        res[1] = left[0] + right[0] + root.val;
        return res;
    }
}

三刷

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public int rob(TreeNode root) {
        if(root == null) return 0;
        int[] res = robSub(root);
        return Math.max(res[0], res[1]);
    }
    
    private int[] robSub(TreeNode root){
        if(root == null) return new int[2];
        int[] left = robSub(root.left);
        int[] right = robSub(root.right);
        int[] res = new int[2];
        res[0] = Math.max(left[0], left[1]) + Math.max(right[0], right[1]);
        res[1] = root.val + left[0] + right[0];//rob the root
        return res;
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末藻茂,一起剝皮案震驚了整個濱河市驹暑,隨后出現(xiàn)的幾起案子玫恳,更是在濱河造成了極大的恐慌,老刑警劉巖优俘,帶你破解...
    沈念sama閱讀 211,265評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件京办,死亡現(xiàn)場離奇詭異,居然都是意外死亡帆焕,警方通過查閱死者的電腦和手機惭婿,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評論 2 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來视搏,“玉大人审孽,你說我怎么就攤上這事』肽龋” “怎么了佑力?”我有些...
    開封第一講書人閱讀 156,852評論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長筋遭。 經(jīng)常有香客問我打颤,道長,這世上最難降的妖魔是什么漓滔? 我笑而不...
    開封第一講書人閱讀 56,408評論 1 283
  • 正文 為了忘掉前任编饺,我火速辦了婚禮,結(jié)果婚禮上响驴,老公的妹妹穿的比我還像新娘透且。我一直安慰自己,他們只是感情好豁鲤,可當我...
    茶點故事閱讀 65,445評論 5 384
  • 文/花漫 我一把揭開白布秽誊。 她就那樣靜靜地躺著,像睡著了一般琳骡。 火紅的嫁衣襯著肌膚如雪锅论。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,772評論 1 290
  • 那天楣号,我揣著相機與錄音最易,去河邊找鬼。 笑死炫狱,一個胖子當著我的面吹牛藻懒,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播视译,決...
    沈念sama閱讀 38,921評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼嬉荆,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了憎亚?” 一聲冷哼從身側(cè)響起员寇,我...
    開封第一講書人閱讀 37,688評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎第美,沒想到半個月后蝶锋,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,130評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡什往,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,467評論 2 325
  • 正文 我和宋清朗相戀三年扳缕,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片别威。...
    茶點故事閱讀 38,617評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡躯舔,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出省古,到底是詐尸還是另有隱情粥庄,我是刑警寧澤,帶...
    沈念sama閱讀 34,276評論 4 329
  • 正文 年R本政府宣布豺妓,位于F島的核電站惜互,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏琳拭。R本人自食惡果不足惜训堆,卻給世界環(huán)境...
    茶點故事閱讀 39,882評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望白嘁。 院中可真熱鬧坑鱼,春花似錦、人聲如沸絮缅。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,740評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽盟蚣。三九已至黍析,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間屎开,已是汗流浹背阐枣。 一陣腳步聲響...
    開封第一講書人閱讀 31,967評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留奄抽,地道東北人蔼两。 一個月前我還...
    沈念sama閱讀 46,315評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像逞度,于是被迫代替她去往敵國和親额划。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,486評論 2 348

推薦閱讀更多精彩內(nèi)容