代码随想录训练营第四十八天|198.打家劫舍,213.打家劫舍II,337.打家劫舍III
创始人
2025-05-31 14:54:10

198.打家劫舍

题目链接:https://leetcode.cn/problems/house-robber/submissions/

代码:

class Solution {
public:int rob(vector& nums) {int n = nums.size();vector dp(n,0);dp[0] = nums[0];if(n == 1)return dp[0];dp[1] = nums[1];for(int i = 2; i < n; i++){dp[i] = max(dp[i-2] + nums[i],dp[i-1]-nums[i-1]+nums[i]);}if(dp[n-1] > dp[n-2])return dp[n-1];else return dp[n-2];}
};

方法二:

class Solution {
public:int rob(vector& nums) {if (nums.size() == 0) return 0;if (nums.size() == 1) return nums[0];vector dp(nums.size());dp[0] = nums[0];dp[1] = max(nums[0], nums[1]);for (int i = 2; i < nums.size(); i++) {dp[i] = max(dp[i - 2] + nums[i], dp[i - 1]);}return dp[nums.size() - 1];}
};

两种方法从dp[1]开始不一样

213.打家劫舍II

题目链接:https://leetcode.cn/problems/house-robber-ii/submissions/

代码:

class Solution {
public:int value(vector& nums,int left,int right){int n = nums.size();if(left == right)return nums[left];vector dp(n,0);dp[left] = nums[left];dp[left+1] = max(nums[left],nums[left+1]);for(int i = left + 2; i <= right; i++){dp[i] = max(dp[i-2] + nums[i], dp[i-1]);}return dp[right];}int rob(vector& nums) {int n = nums.size();if(n == 1)return nums[0];int nums1 = value(nums,0,n-2);int nums2 = value(nums,1,n-1);if(nums1 > nums2)return nums1;else return nums2;}
};

对于一个数组,成环的话主要有如下三种情况:

  • 情况一:考虑不包含首尾元素

  • 情况二:考虑包含首元素,不包含尾元素

  • 情况三:考虑包含尾元素,不包含首元素

注意我这里用的是"考虑",例如情况三,虽然是考虑包含尾元素,但不一定要选尾部元素! 对于情况三,取nums[1] 和 nums[3]就是最大的。

而情况二 和 情况三 都包含了情况一了,所以只考虑情况二和情况三就可以了。

337.打家劫舍III

题目链接:https://leetcode.cn/problems/house-robber-iii/submissions/

代码(暴力解法):

class Solution {
public:int rob(TreeNode* root) {if(root == nullptr)return 0;int val1 = root->val;if(root->left)val1 += rob(root->left->right) + rob(root->left->left);if(root->right)val1 += rob(root->right->right) + rob(root->right->left);int val2 = rob(root->left) + rob(root->right);if(val2 > val1)return val2;elsereturn val1;}
};

代码:

class Solution {
public:// 长度为2的数组,0:不偷,1:偷vector robTree(TreeNode* cur){if(cur == nullptr)return vector{0,0};vector left = robTree(cur->left);vector right = robTree(cur->right);// 偷cur,那么就不能偷左右节点int val1 = cur->val + left[0] + right[0];// 不偷curint val2 = max(left[0],left[1]) + max(right[0],right[1]);return vector{val2,val1};}int rob(TreeNode* root) {vector result = robTree(root);if(result[0] > result[1])return result[0];elsereturn result[1];}
};

dp数组(dp table)以及下标的含义:下标为0记录不偷该节点所得到的的最大金钱,下标为1记录偷该节点所得到的的最大金钱。

分情况讨论

相关内容

热门资讯

面对面做好群众工作 党的作风关系党的形象,关系人心向背,关系党的生死存亡。作风问题的核心是党同人民群众的关系问题。广大党...
环保税征管迎来“数字监督员”   近年来,山西省太原市尖草坪区检察院以“数字检察”战略为引领,运用大数据办案思维,依托大数据法律监...
重庆华森制药股份有限公司关于公... 证券代码:002907 证券简称:华森制药 公告编号:2025-088重庆华森制药股份有限公司关于...
用实绩实效彰显使命担当 新华社记者  王 希  王悦阳中央企业负责人会议12月22日至23日在京召开。会上传达了习近平总书记...
文艺复兴古城秋日法治絮语    刘静坤教授在意大利费拉拉大学作学术讲座。  近日,我应邀在意大利费拉拉大学进行系列学术讲座。古...