[LeetCode] 337. 打家劫舍III ☆☆☆(动态规划)

https://leetcode-cn.com/problems/house-robber-iii/solution/tong-yong-si-lu-tuan-mie-da-jia-jie-she-wen-ti-b-2/

描述

在上次打劫完一条街道之后和一圈房屋后,小偷又发现了一个新的可行窃的地区。这个地区只有一个入口,我们称之为“根”。 除了“根”之外,每栋房子有且只有一个“父“房子与之相连。一番侦察之后,聪明的小偷意识到“这个地方的所有房屋的排列类似于一棵二叉树”。 如果两个直接相连的房子在同一天晚上被打劫,房屋将自动报警。

计算在不触动警报的情况下,小偷一晚能够盗取的最高金额。

示例 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.

解析

参考打家劫舍1、2。

整体的思路完全没变,还是做抢或者不抢的选择,去收益较大的选择。

代码

Map<TreeNode, Integer> memo = new HashMap<>();
public int rob(TreeNode root) {
    if (root == null) return 0;
    // 利用备忘录消除重叠子问题
    if (memo.containsKey(root))
        return memo.get(root);
    // 抢,然后去下下家
    int do_it = root.val
        + (root.left == null ?
            0 : rob(root.left.left) + rob(root.left.right))
        + (root.right == null ?
            0 : rob(root.right.left) + rob(root.right.right));
    // 不抢,然后去下家
    int not_do = rob(root.left) + rob(root.right);

    int res = Math.max(do_it, not_do);
    memo.put(root, res);
    return res;
}

时间复杂度 O(N),N 为数的节点数。

原文地址:https://www.cnblogs.com/fanguangdexiaoyuer/p/12642854.html

时间: 2024-10-09 10:49:49

[LeetCode] 337. 打家劫舍III ☆☆☆(动态规划)的相关文章

[LeetCode] 337. 打家劫舍 III (树形dp)

题目 在上次打劫完一条街道之后和一圈房屋后,小偷又发现了一个新的可行窃的地区.这个地区只有一个入口,我们称之为"根". 除了"根"之外,每栋房子有且只有一个"父"房子与之相连.一番侦察之后,聪明的小偷意识到"这个地方的所有房屋的排列类似于一棵二叉树". 如果两个直接相连的房子在同一天晚上被打劫,房屋将自动报警. 计算在不触动警报的情况下,小偷一晚能够盗取的最高金额. 示例 1: 输入: [3,2,3,null,3,null,1

Leetcode 337. 打家劫舍 III

/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class Solution { public: struct returnData { int qu; int buqu; returnData(int

[LeetCode] 198. 打家劫舍II ☆☆☆(动态规划)

描述 你是一个专业的小偷,计划偷窃沿街的房屋,每间房内都藏有一定的现金.这个地方所有的房屋都围成一圈,这意味着第一个房屋和最后一个房屋是紧挨着的.同时,相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警. 给定一个代表每个房屋存放金额的非负整数数组,计算你在不触动警报装置的情况下,能够偷窃到的最高金额. 示例 1: 输入: [2,3,2]输出: 3解释: 你不能先偷窃 1 号房屋(金额 = 2),然后偷窃 3 号房屋(金额 = 2), 因为他们是相邻的.示例

力扣337——打家劫舍 III

这一篇也是基于"打家劫舍"的扩展,需要针对特殊情况特殊考虑,当然其本质还是动态规划,优化时需要考虑数据结构. 原题 在上次打劫完一条街道之后和一圈房屋后,小偷又发现了一个新的可行窃的地区.这个地区只有一个入口,我们称之为"根". 除了"根"之外,每栋房子有且只有一个"父"房子与之相连.一番侦察之后,聪明的小偷意识到"这个地方的所有房屋的排列类似于一棵二叉树". 如果两个直接相连的房子在同一天晚上被打劫,房屋

337. 打家劫舍 III

在上次打劫完一条街道之后和一圈房屋后,小偷又发现了一个新的可行窃的地区.这个地区只有一个入口,我们称之为“根”. 除了“根”之外,每栋房子有且只有一个“父“房子与之相连.一番侦察之后,聪明的小偷意识到“这个地方的所有房屋的排列类似于一棵二叉树”. 如果两个直接相连的房子在同一天晚上被打劫,房屋将自动报警. 计算在不触动警报的情况下,小偷一晚能够盗取的最高金额. 示例 1: 输入: [3,2,3,null,3,null,1] 3 / \ 2 3 \ \ 3 1 输出: 7 解释: 小偷一晚能够盗取

337. 打家劫舍 III(树上dp)

在上次打劫完一条街道之后和一圈房屋后,小偷又发现了一个新的可行窃的地区.这个地区只有一个入口,我们称之为“根”. 除了“根”之外,每栋房子有且只有一个“父“房子与之相连.一番侦察之后,聪明的小偷意识到“这个地方的所有房屋的排列类似于一棵二叉树”. 如果两个直接相连的房子在同一天晚上被打劫,房屋将自动报警. 计算在不触动警报的情况下,小偷一晚能够盗取的最高金额. 示例 1: 输入: [3,2,3,null,3,null,1] 3    / \   2   3    \   \      3   1

[LeetCode]Best Time to Buy and Sell Stock III 动态规划

本题是Best Time to Buy and Sell Stock/的改进版. 本题中,可以买最多买进卖出两次股票. 买两次股票可以看成是第0~i天买进卖出以及第i+1~n-1天买进卖出两部分.这要枚举i并求出0th~ith的最大利益与(i+1)th~(n-1)th的最大利益之和的最大值就是买进卖出两次可以得到的最大利益.即状态转移方程: dp[0,n-1]=max{dp[0,k]+dp[k+1,n-1]},k=1,...,n-2 而只买进卖出一次的最大利润通过0th~ith可以求得. 这里求

[leetcode] 337.House Robber III

The thief has found himself a new place for his thievery again. There is only one entrance to this area, called the "root." Besides the root, each house has one and only one parent house. After a tour, the smart thief realized that "all hou

【LeetCode 337 &amp; 329. memorization DFS】House Robber III

/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class Solution { public: //递归程序就是结构演绎,有点像dp,只要定义好每一次递归过程完成的是同一个目标,就能保证所有递归结束之后