337. 打家劫舍 III
小偷又发现了一个新的可行窃的地区。这个地区只有一个入口,我们称之为 root
。
除了 root
之外,每栋房子有且只有一个“父“房子与之相连。一番侦察之后,聪明的小偷意识到“这个地方的所有房屋的排列类似于一棵二叉树”。 如果 两个直接相连的房子在同一天晚上被打劫 ,房屋将自动报警。
给定二叉树的 root
。返回 在不触动警报的情况下 ,小偷能够盗取的最高金额 。
示例 1:
输入: root = [3,2,3,null,3,null,1] 输出: 7 解释: 小偷一晚能够盗取的最高金额 3 + 3 + 1 = 7
示例 2:
输入: root = [3,4,5,1,3,null,1] 输出: 9 解释: 小偷一晚能够盗取的最高金额 4 + 5 = 9
提示:
[1, 104]
范围内0 <= Node.val <= 104
原站题解
php 解法, 执行用时: 12 ms, 内存消耗: 21.1 MB, 提交时间: 2023-09-18 09:29:27
/** * Definition for a binary tree node. * class TreeNode { * public $val = null; * public $left = null; * public $right = null; * function __construct($val = 0, $left = null, $right = null) { * $this->val = $val; * $this->left = $left; * $this->right = $right; * } * } */ class Solution { /** * @param TreeNode $root * @return Integer */ function rob($root) { $ans = $this->dfs($root); return max($ans[0], $ans[1]); } function dfs($node) { if ($node == null) return [0, 0]; $l = $this->dfs($node->left); $r = $this->dfs($node->right); // 选了根节点,那么能选的只有左/右子树没选的子节点 $selected = $node->val + $l[1] + $r[1]; // 不选根节点,左右子树各选一个 $notSelected = max($l[0], $l[1]) + max($r[0], $r[1]); return [$selected, $notSelected]; } }
rust 解法, 执行用时: 0 ms, 内存消耗: 2.9 MB, 提交时间: 2023-09-16 11:09:27
// Definition for a binary tree node. // #[derive(Debug, PartialEq, Eq)] // pub struct TreeNode { // pub val: i32, // pub left: Option<Rc<RefCell<TreeNode>>>, // pub right: Option<Rc<RefCell<TreeNode>>>, // } // // impl TreeNode { // #[inline] // pub fn new(val: i32) -> Self { // TreeNode { // val, // left: None, // right: None // } // } // } use std::rc::Rc; use std::cell::RefCell; impl Solution { pub fn sub_rob(node: &Option<Rc<RefCell<TreeNode>>>) -> [i32; 2] { if let Some(n) = node { let dp_l = Self::sub_rob(&n.borrow().left); let dp_r = Self::sub_rob(&n.borrow().right); [dp_l[1] + dp_r[1], (dp_l[0] + dp_r[0] + n.borrow().val).max(dp_l[1] + dp_r[1])] } else { [0; 2] } } pub fn rob(root: Option<Rc<RefCell<TreeNode>>>) -> i32 { Self::sub_rob(&root)[1] } pub fn rob2(root: Option<Rc<RefCell<TreeNode>>>) -> i32 { fn dfs(root: Option<Rc<RefCell<TreeNode>>>) -> (i32, i32) { if let Some(root) = root { let left = dfs(root.borrow_mut().left.take()); let right = dfs(root.borrow_mut().right.take()); ( root.borrow().val + left.1 + right.1, left.0.max(left.1) + right.0.max(right.1), ) } else { (0, 0) } } // a:需要偷根节点的情况 // b:不偷根节点的情况 let (a, b) = dfs(root); a.max(b) } }
cpp 解法, 执行用时: 16 ms, 内存消耗: 21.9 MB, 提交时间: 2023-09-16 11:08:15
/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode() : val(0), left(nullptr), right(nullptr) {} * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} * }; */ class Solution { pair<int, int> dfs(TreeNode *node) { if (node == nullptr) // 递归边界 return {0, 0}; // 没有节点,怎么选都是 0 auto [l_rob, l_not_rob] = dfs(node->left); // 递归左子树 auto [r_rob, r_not_rob] = dfs(node->right); // 递归右子树 int rob = l_not_rob + r_not_rob + node->val; // 选 int not_rob = max(l_rob, l_not_rob) + max(r_rob, r_not_rob); // 不选 return {rob, not_rob}; } public: int rob(TreeNode *root) { auto [root_rob, root_not_rob] = dfs(root); return max(root_rob, root_not_rob); // 根节点选或不选的最大值 } };
python3 解法, 执行用时: 64 ms, 内存消耗: 18.5 MB, 提交时间: 2023-09-16 11:07:21
# Definition for a binary tree node. # class TreeNode: # def __init__(self, val=0, left=None, right=None): # self.val = val # self.left = left # self.right = right class Solution: def rob(self, root: Optional[TreeNode]) -> int: def dfs(node: Optional[TreeNode]) -> (int, int): if node is None: # 递归边界 return 0, 0 # 没有节点,怎么选都是 0 l_rob, l_not_rob = dfs(node.left) # 递归左子树 r_rob, r_not_rob = dfs(node.right) # 递归右子树 rob = l_not_rob + r_not_rob + node.val # 选 not_rob = max(l_rob, l_not_rob) + max(r_rob, r_not_rob) # 不选 return rob, not_rob return max(dfs(root)) # 根节点选或不选的最大值
golang 解法, 执行用时: 4 ms, 内存消耗: 5.3 MB, 提交时间: 2022-12-04 11:46:07
/** * Definition for a binary tree node. * type TreeNode struct { * Val int * Left *TreeNode * Right *TreeNode * } */ func rob(root *TreeNode) int { val := dfs(root) return max(val[0], val[1]) } func dfs(node *TreeNode) []int { if node == nil { return []int{0, 0} } l, r := dfs(node.Left), dfs(node.Right) selected := node.Val + l[1] + r[1] notSelected := max(l[0], l[1]) + max(r[0], r[1]) return []int{selected, notSelected} } func max(x, y int) int { if x > y { return x } return y }
javascript 解法, 执行用时: 76 ms, 内存消耗: 45.6 MB, 提交时间: 2022-12-04 11:45:40
/** * Definition for a binary tree node. * function TreeNode(val, left, right) { * this.val = (val===undefined ? 0 : val) * this.left = (left===undefined ? null : left) * this.right = (right===undefined ? null : right) * } */ /** * @param {TreeNode} root * @return {number} */ var rob = function(root) { const dfs = (node) => { if (node === null) { return [0, 0]; } const l = dfs(node.left); const r = dfs(node.right); const selected = node.val + l[1] + r[1]; const notSelected = Math.max(l[0], l[1]) + Math.max(r[0], r[1]); return [selected, notSelected]; } const rootStatus = dfs(root); return Math.max(rootStatus[0], rootStatus[1]); };
java 解法, 执行用时: 0 ms, 内存消耗: 40.8 MB, 提交时间: 2022-12-04 11:45:28
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode() {} * TreeNode(int val) { this.val = val; } * TreeNode(int val, TreeNode left, TreeNode right) { * this.val = val; * this.left = left; * this.right = right; * } * } */ class Solution { public int rob(TreeNode root) { int[] rootStatus = dfs(root); return Math.max(rootStatus[0], rootStatus[1]); } public int[] dfs(TreeNode node) { if (node == null) { return new int[]{0, 0}; } int[] l = dfs(node.left); int[] r = dfs(node.right); int selected = node.val + l[1] + r[1]; int notSelected = Math.max(l[0], l[1]) + Math.max(r[0], r[1]); return new int[]{selected, notSelected}; } }
java 解法, 执行用时: 3 ms, 内存消耗: 41.2 MB, 提交时间: 2022-12-04 11:45:15
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode() {} * TreeNode(int val) { this.val = val; } * TreeNode(int val, TreeNode left, TreeNode right) { * this.val = val; * this.left = left; * this.right = right; * } * } */ class Solution { Map<TreeNode, Integer> f = new HashMap<TreeNode, Integer>(); Map<TreeNode, Integer> g = new HashMap<TreeNode, Integer>(); public int rob(TreeNode root) { dfs(root); return Math.max(f.getOrDefault(root, 0), g.getOrDefault(root, 0)); } public void dfs(TreeNode node) { if (node == null) { return; } dfs(node.left); dfs(node.right); f.put(node, node.val + g.getOrDefault(node.left, 0) + g.getOrDefault(node.right, 0)); g.put(node, Math.max(f.getOrDefault(node.left, 0), g.getOrDefault(node.left, 0)) + Math.max(f.getOrDefault(node.right, 0), g.getOrDefault(node.right, 0))); } }
javascript 解法, 执行用时: 84 ms, 内存消耗: 47.2 MB, 提交时间: 2022-12-04 11:44:56
/** * Definition for a binary tree node. * function TreeNode(val, left, right) { * this.val = (val===undefined ? 0 : val) * this.left = (left===undefined ? null : left) * this.right = (right===undefined ? null : right) * } */ /** * @param {TreeNode} root * @return {number} */ var rob = function(root) { const f = new Map(); const g = new Map(); const dfs = (node) => { if (node === null) { return; } dfs(node.left); dfs(node.right); f.set(node, node.val + (g.get(node.left) || 0) + (g.get(node.right) || 0)); g.set(node, Math.max(f.get(node.left) || 0, g.get(node.left) || 0) + Math.max(f.get(node.right) || 0, g.get(node.right) || 0)); } dfs(root); return Math.max(f.get(root) || 0, g.get(root) || 0); };