代码随想录训练营第四十八天|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记录偷该节点所得到的的最大金钱。

分情况讨论

相关内容

热门资讯

中国公民遭遇“李鬼”电诈,中领... 1月21日,中国驻珀斯总领馆发布提醒:近期,总领馆接到中国公民遭遇电信诈骗的求助,受害人具有一定防范...
格陵兰岛自治政府建议民众备好五... 当地时间1月21日,格陵兰岛自治政府发布了一份应急手册,建议当地居民准备好五天的生活必需品,其中包括...
欧洲议会提交司法审查,欧盟-南... 新华社布鲁塞尔1月21日电(记者康逸 张馨文)欧洲议会21日投票通过将欧盟-南共市自贸协定提交欧盟法...
首个海上液体火箭发射回收试验平... 每天3分钟,速览天下事1月22日星期四,农历腊月初四封面新闻首个海上液体火箭发射回收试验平台将投用 ...
睿行丨破局与新生: 一场抵押经... (来源:现代商业银行杂志)文|中国工商银行浙江衢州廿里支行  卢余铖韦总的案例并非个例,它揭示了一个...