diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\346\212\242\346\210\277\345\255\220.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\346\212\242\346\210\277\345\255\220.md" index eeefc0190d26af3dcff87603e3e0c145c6c681fc..e931b4e5244178aa2ad511d93d299beb53fd760a 100644 --- "a/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\346\212\242\346\210\277\345\255\220.md" +++ "b/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\346\212\242\346\210\277\345\255\220.md" @@ -230,9 +230,122 @@ int[] dp(TreeNode root) { ![labuladong](../pictures/labuladong.jpg) +[5ooo](https://github.com/5ooo) 提供 House Robber I C++ 解法代码: + +```c++ +class Solution { +public: + int rob(vector& nums) { + int dp_i = 0; //第i间房子最多能抢的钱 + int dp_i_1 = 0; //第i+1间房子最多能抢的钱 + int dp_i_2 = 0; //第i+2间房子最多能抢的钱 + + //从最后一间房子开始,往前移动 + for (int i = nums.size() - 1; i >= 0; i--) { + dp_i = max(dp_i_1, nums[i] + dp_i_2); + dp_i_2 = dp_i_1; + dp_i_1 = dp_i; + } + + return dp_i; + } +}; +``` + +[5ooo](https://github.com/5ooo) 提供 House Robber II C++ 解法代码: + +```c++ +class Solution { +public: + int rob(vector& nums) { + if (nums.size() == 1) + return nums[0]; + + return max(robRange(nums, 0, nums.size() - 2), + robRange(nums, 1, nums.size() - 1)); + } + + int robRange(vector& nums, int start, int end) { + int dp_i = 0; //第i间房子最多能抢的钱 + int dp_i_1 = 0; //第i+1间房子最多能抢的钱 + int dp_i_2 = 0; //第i+2间房子最多能抢的钱 + + for (int i = end; i >= start; i--) { + dp_i = max(dp_i_1, nums[i] + dp_i_2); + dp_i_2 = dp_i_1; + dp_i_1 = dp_i; + } + + return dp_i; + } +}; +``` + +[5ooo](https://github.com/5ooo) 提供 House Robber III C++ 解法代码: + +```c++ +class Solution { +public: + int rob(TreeNode* root) { + if (root == nullptr) + return 0; + + // 利用备忘录消除重叠子问题 + if (memo.find(root) != memo.end()) + return memo[root]; + + // 抢,然后去下下家 + int do_it = root->val + + (root->left == nullptr ? + 0 : rob(root->left->left) + rob(root->left->right)) + + (root->right == nullptr ? + 0 : rob(root->right->left) + rob(root->right->right)); + + // 不抢,然后去下家 + int not_do = rob(root->left) + rob(root->right); + + int ret = max(do_it, not_do); + memo[root] = ret; + + return ret; + } +private: + unordered_map memo; +}; +``` + +```c++ +class Solution { +public: + int rob(TreeNode* root) { + //ret[0]表示不抢root,获取的最大钱数 + //ret[1]表示抢root,获取的最大钱数 + vector ret = dp(root); + return max(ret[0], ret[1]); + } + + + vector dp(TreeNode* root) { + if (root == nullptr) + return {0, 0}; + + vector left = dp(root->left); + vector right = dp(root->right); + + //抢当前的,则接下来不能抢 + int rob = root->val + left[0] + right[0]; + + //不抢当前的,接下来可抢可不抢,取收益大的 + int not_rob = max(left[0], left[1]) + max(right[0], right[1]); + + return {not_rob, rob}; + } +}; +``` [上一篇:团灭 LeetCode 股票买卖问题](../动态规划系列/团灭股票问题.md) [下一篇:动态规划之四键键盘](../动态规划系列/动态规划之四键键盘.md) -[目录](../README.md#目录) \ No newline at end of file +[目录](../README.md#目录) +