Leetcode 337打家劫舍 III

2022-03-27 00:08:51 字數 1725 閱讀 6068

在上次打劫完一條街道之後和一圈房屋後,小偷又發現了乙個新的可行竊的地區。這個地區只有乙個入口,我們稱之為「根」。

除了「根」之外,每棟房子有且只有乙個「父「房子與之相連。一番偵察之後,聰明的小偷意識到「這個地方的所有房屋的排列類似於一棵二叉樹」。

如果兩個直接相連的房子在同一天晚上被打劫,房屋將自動報警。

計算在不觸動警報的情況下,小偷一晚能夠盜取的最高金額。

示例 1:

輸入: [3,2,3,null,3,null,1]

3/ \

2 3

\ \

3 1

輸出: 7

解釋: 小偷一晚能夠盜取的最高金額 = 3 + 3 + 1 = 7.

示例 2:

輸入: [3,4,5,1,3,null,1]

3/ \

4 5

/ \ \

1 3 1

輸出: 9

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

使用爺爺、兩個孩子、4 個孫子來說明問題

首先來定義這個問題的狀態

爺爺節點獲取到最大的偷取的錢數呢

首先要明確相鄰的節點不能偷,也就是爺爺選擇偷,兒子就不能偷了,但是孫子可以偷

二叉樹只有左右兩個孩子,乙個爺爺最多 2 個兒子,4 個孫子

根據以上條件,我們可以得出單個節點的錢該怎麼算

4 個孫子偷的錢 + 爺爺的錢 vs 兩個兒子偷的錢哪個組合錢多,就當做當前節點能偷的最大錢數。這就是動態規劃裡面的最優子結構

class solution 

}

class solution 

private int robinternal(treenode root,hashmapmemo)

if(root.right != null)

int result = math.max(money,robinternal(root.left,memo)+ robinternal(root.right,memo));

memo.put(root,result);

return result;

}}

/*

思路改進:

我們換一種辦法來定義此問題

每個節點可選擇偷或者不偷兩種狀態,根據題目意思,相連節點不能一起偷

當前節點擊擇偷時,那麼兩個孩子節點就不能選擇偷了

當前節點擊擇不偷時,兩個孩子節點只需要拿最多的錢出來

就行(兩個孩子節點偷不偷沒關係)

我們使用乙個大小為 2 的陣列來表示

int res = new int[2] 0 代表不偷,1 代表偷

任何乙個節點能偷到的最大錢的狀態可以定義為

當前節點擊擇不偷:

當前節點能偷到的最大錢數 = 左孩子能偷到的錢 + 右孩子能偷到的錢

當前節點擊擇偷:

當前節點能偷到的最大錢數 = 左孩子選擇自己不偷時能得到的錢 +

右孩子選擇不偷時能得到的錢 +

當前節點的錢數

*/public int rob(treenode root)

public int robinternal(treenode root)

LeetCode337 打家劫舍

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

leetcode337打家劫舍III

不搶劫該節點,則可以搶劫該節點的左右字節點 注意,node節點不搶不意味著一定要搶它的左右子結點,所以在方法中應該呼叫rob方法,而不是robinclude方法 public int robexclude treenode node return rob node.left rob node.rig...

Leetcode 337 打家劫舍 III

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