打家劫舍III(力扣第337題)

2022-06-16 11:30:14 字數 1600 閱讀 7513

題目:

在上次打劫完一條街道之後和一圈房屋後,小偷又發現了乙個新的可行竊的地區。這個地區只有乙個入口,我們稱之為「根」。 除了「根」之外,每棟房子有且只有乙個「父「房子與之相連。一番偵察之後,聰明的小偷意識到「這個地方的所有房屋的排列類似於一棵二叉樹」。 如果兩個直接相連的房子在同一天晚上被打劫,房屋將自動報警。計算在不觸動警報的情況下,小偷一晚能夠盜取的最高金額。

示例 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 /\ \ 1

31輸出:

9解釋: 小偷一晚能夠盜取的最高金額 = 4 + 5 = 9.

分析:

透過現象看本質,其實就是鄰近節點的值不能同時獲取,求出所能獲取的最大和。對於二叉樹問題,一般從最簡單的情況去分析,然後進行一系列的重複性遞迴操作即可解決。我們將二叉樹分為三個部分,第一部分是父親結點,第二部分是兩個左右子結點,第三部分是兩個左右子節點的所有子樹。為什麼要分成這幾個部分呢?那是因為根據題意可知,父親結點的值和其左右子結點的值是不可兼得的,左右子結點的值和它們各自的孩子結點的值是不可兼得的,但是左右子結點的父親結點的值和左右子結點的孩子結點的值可以兼得,因為第一部分的父親結點一定和其左右子結點的所有子樹結點不直接相連所以無論第三部分的子樹們如何選定具體的結點,只需保證第三部分都是基於它們那些子樹情況下的最大和即可(這就涉及了遞迴),最終我們將第一部分和第三部分相加與第二部分的值進行比較,哪個大就返回哪個即可。

其中第三部分是不一定存在的,如果第三部分不存在,那麼就只用第一部分和第二部分進行比較。

**:

public

introb(treenode root)

getmaxmoney(root);

return

getmaxmoney(root);

}private

intgetmaxmoney(treenode root)

if (root.left == null && root.right == null

)

int childmoney = getmaxmoney(root.left) +getmaxmoney(root.right);

int fathermoney =root.val;

if (root.left != null

)

if (root.right != null

)

return

math.max(fathermoney,childmoney);

}

LeetCode 第337題打家劫舍 III

題目描述 在上次打劫完一條街道之後和一圈房屋後,小偷又發現了乙個新的可行竊的地區。這個地區只有乙個入口,我們稱之為 根 除了 根 之外,每棟房子有且只有乙個 父 房子與之相連。一番偵察之後,聰明的小偷意識到 這個地方的所有房屋的排列類似於一棵二叉樹 如果兩個直接相連的房子在同一天晚上被打劫,房屋將自...

力扣之337 打家劫舍 III

在上次打劫完一條街道之後和一圈房屋後,小偷又發現了乙個新的可行竊的地區。這個地區只有乙個入口,我們稱之為 根 除了 根 之外,每棟房子有且只有乙個 父 房子與之相連。一番偵察之後,聰明的小偷意識到 這個地方的所有房屋的排列類似於一棵二叉樹 如果兩個直接相連的房子在同一天晚上被打劫,房屋將自動報警。計...

LeetCode337 樹 打家劫舍 III

遞迴求解 本質上就是間隔遍歷 把問題直接簡化成兩個部分 偷父節點。那就是隔行遍歷左右節點,因為不能偷連續的節點。但是注意,隔行遍歷一定要判斷有無空指標!不偷父節點。可以畫幾個示意圖看看,不偷父節點的話就是父節點的左子樹 右子樹的值,依次加下去 最後返回乙個最大的金額 class solution i...