LintCode:M-搶劫房屋|||
阿新 • • 發佈:2019-02-02
在上次打劫完一條街道之後和一圈房屋之後,竊賊又發現了一個新的可以打劫的地方,但這次所有的房子組成的區域比較奇怪,聰明的竊賊考察地形之後,發現這次的地形是一顆二叉樹。與前兩次偷竊相似的是每個房子都存放著特定金額的錢。你面臨的唯一約束條件是:相鄰的房子裝著相互聯絡的防盜系統,且當相鄰的兩個房子同一天被打劫時,該系統會自動報警。
算一算,如果今晚去打劫,你最多可以得到多少錢,當然在不觸動報警裝置的情況下。
您在真實的面試中是否遇到過這個題? Yes 樣例 3
/ \
2 3
\ \
3 1
竊賊最多能偷竊的金錢數是 3 + 3 + 1 = 7.
3 / \ 4 5 / \ \ 1 3 1
竊賊最多能偷竊的金錢數是 4 + 5 = 9.
/** * Definition of TreeNode: * public class TreeNode { * public int val; * public TreeNode left, right; * public TreeNode(int x) { val = x; } * } */ public class Solution { /* * @param root: The root of binary tree. * @return: The maximum amount of money you can rob tonight */ public int houseRobber3(TreeNode root) { int[] res = rob2(root); return Math.max(res[0],res[1]); } //方法一 //後序遍歷 //返回res[0]表示搶劫該node後的最大值,res[1]表示不搶後的最大值 int[] rob2(TreeNode node){ int[] res = new int[2]; if(node==null) return res; int[] left = rob2(node.left); int[] right = rob2(node.right); //不搶node res[0] = Math.max(left[0],left[1])+Math.max(right[0], right[1]); //搶node res[1] = left[0]+right[0]+node.val; return res; } //方法二 //AC=91%,超時 //因為if(robFlag==0)時,會有重複計算 public int houseRobber3_2(TreeNode root) { if(root==null) return 0; int la = rob(root.left, 0); int ra = rob(root.right, 0); int lb = rob(root.left, 1); int rb = rob(root.right, 1); return Math.max(la+ra, lb+rb+root.val); } //robFlag:1=搶劫node.parent, 0=不搶劫node.parent int rob(TreeNode node, int robFlag){ if(node==null) return 0; int leftSum, rightSum; if(robFlag==0){//不搶劫node.parent,node可以搶或不搶 //搶node leftSum = rob(node.left, 1); rightSum = rob(node.right, 1); //不搶node int lTmp = rob(node.left, 0); int rTmp = rob(node.right, 0); return Math.max(leftSum+rightSum+node.val, lTmp+rTmp); }else{//搶劫node.parent,node不可以搶 //不搶node leftSum = rob(node.left, 0); rightSum = rob(node.right, 0); return leftSum+rightSum; } } }