在上次打劫完一條街道之後和一圈房屋後,小偷又發現了乙個新的可行竊的地區。這個地區只有乙個入口,我們稱之為「根」。 除了「根」之外,每棟房子有且只有乙個「父「房子與之相連。一番偵察之後,聰明的小偷意識到「這個地方的所有房屋的排列類似於一棵二叉樹」。 如果兩個直接相連的房子在同一天晚上被打劫,房屋將自動報警。
計算在不觸動警報的情況下,小偷一晚能夠盜取的最高金額。
示例1
輸入:[3
,2,3
,null,
3,null,1]
3/ \
23 \ \
31輸出:
7 解釋: 小偷一晚能夠盜取的最高金額 =3+
3+1=
7.
示例2輸入:[3
,4,5
,1,3
,null,1]
3/ \
45/ \ \ 13
1輸出:
9解釋: 小偷一晚能夠盜取的最高金額 =4+
5=9.
解題思路:
使用動態規劃求解
其中需要用到map的資料結構來存放求出的過程,避免重複計算
若直接計算,則會出現大量重複計算,就會導致超出時間限制。
演算法過程:
加入輸入的是示例2
輸入:[3
,4,5
,1,3
,null,1]
3//祖父
/ \ 4
5//父親
/ \ \ 13
1//兒子
那麼就有兩種選擇:
1、選擇祖父和兒子
即選擇 3、1、3、1 它們的和為8
2、選擇父親
即選擇 4、 5 它們的和為9
3、選取這兩種方案的最大值
下面為直接計算的過程:(注意,該寫法時間太長,不會通過測試)
int
rob(treenode* root)
int money = root-
>val;
if(root-
>left)
if(root-
>right)
int temp =
rob(root-
>left)
+rob
(root-
>right)
;return
max(money,temp)
;}
下面為ac**:(只是在上面的基礎上稍微修改)
/**
* definition for a binary tree node.
* struct treenode
* };
*/class
solution
if(m.
find
(root)
!= m.
end())
//選擇祖父和兒子
int money = root-
>val;
if(root-
>left)
if(root-
>right)
//選擇父親
int temp =
solve
(root-
>left,m)
+solve
(root-
>right,m)
;int result =
max(money,temp)
; m.
insert
(pair,int
>
(root,result));
return result;
}int
rob(treenode* root)
};
總結:
emmmmm,當個小偷挺難的。
leetcode337打家劫舍III
不搶劫該節點,則可以搶劫該節點的左右字節點 注意,node節點不搶不意味著一定要搶它的左右子結點,所以在方法中應該呼叫rob方法,而不是robinclude方法 public int robexclude treenode node return rob node.left rob node.rig...
Leetcode 337 打家劫舍 III
在上次打劫完一條街道之後和一圈房屋後,小偷又發現了乙個新的可行竊的地區。這個地區只有乙個入口,我們稱之為 根 除了 根 之外,每棟房子有且只有乙個 父 房子與之相連。一番偵察之後,聰明的小偷意識到 這個地方的所有房屋的排列類似於一棵二叉樹 如果兩個直接相連的房子在同一天晚上被打劫,房屋將自動報警。計...
leetcode337 打家劫舍 III
在上次打劫完一條街道之後和一圈房屋後,小偷又發現了乙個新的可行竊的地區。這個地區只有乙個入口,我們稱之為 根 除了 根 之外,每棟房子有且只有乙個 父 房子與之相連。一番偵察之後,聰明的小偷意識到 這個地方的所有房屋的排列類似於一棵二叉樹 如果兩個直接相連的房子在同一天晚上被打劫,房屋將自動報警。計...