● 198.打家劫舍
有点像爬楼梯。
class Solution {
public:
int rob(vector<int>& nums) {
vector<int> dp(nums.size(),0);
if(nums.size()==1)
return nums[0];
dp[0]=nums[0];
dp[1]=max(nums[0],nums[1]);
for(int i=2;i<dp.size();i++)
{
dp[i]=max(dp[i-1],dp[i-2]+nums[i]);
}
return dp[nums.size()-1];
}
};
● 213.打家劫舍II
其实就是在上一题的基础上进行一些改动。其实总共分为三种情况,不取开头和结尾,只取开头,只取结尾,但是实际上第一种情况可以和后两种情况融合,变成两种情况:考虑开头不考虑结尾,考虑结尾不考虑开头。至于取不取开头或者结尾是在这两种情况的函数调用里判断的不需要考虑。对于这种环形的问题我们的一个解题思路就是把环形展开成线性。
class Solution {
public:
int rob(vector<int>& nums) {
if(nums.size()==1)
return nums[0];
vector<int> nums1(nums.begin(),nums.end()-1);
vector<int> nums2(nums.begin()+1,nums.end());
int start=rob1(nums1);
int end=rob1(nums2);
return (max(start,end));
}
int rob1(vector<int>& nums) {
vector<int> dp(nums.size(),0);
if(nums.size()==1)
return nums[0];
dp[0]=nums[0];
dp[1]=max(nums[0],nums[1]);
for(int i=2;i<dp.size();i++)
{
dp[i]=max(dp[i-1],dp[i-2]+nums[i]);
}
return dp[nums.size()-1];
}
};
● 337.打家劫舍III
class Solution {
public:
int rob(TreeNode* root) {
pair<int,int> tmp=steal(root);
return max(tmp.first,tmp.second);
}
pair<int,int> steal(TreeNode *root)
{
int steal_max=0;
int unsteal_max=0;
int leftsteal_max=0;
int rightsteal_max=0;
int leftunsteal_max=0;
int rightunsteal_max=0;
if(root->left!=nullptr)
{
pair<int,int> tmp=steal(root->left);
leftsteal_max=tmp.first;
leftunsteal_max=tmp.second;
}
if(root->right!=nullptr)
{
pair<int,int> tmp=steal(root->right);
rightsteal_max=tmp.first;
rightunsteal_max=tmp.second;
}
steal_max=leftunsteal_max+rightunsteal_max+root->val;
unsteal_max=max(leftsteal_max,leftunsteal_max)+max(rightsteal_max,rightunsteal_max);
pair<int,int> result(steal_max,unsteal_max);
return result;
}
};