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记录偷该节点所得到的的最大金钱。
分情况讨论