2020.2.6更新
假设有:
A B C D E F
两种思路,第一种从A开始算,那么有两种结果,要么偷A,要么不偷,两种结果A+rob(C)和rob(B),这就是递归。这种方法会超时;
第二种,翻过来考虑,如果在F是最后一家,那么最大收益只可能是从D来的或者C跳转来的,不可能是B及之前的,这样某一家的最大等于前面某个最大加上一个数,也就是动态规划。列一个向量,把每一个位置的最优记录下来。而且,只有EF会是最后一家。
递归《==》动态规划
代码:
class Solution {
public:
// int rob(vector<int>& nums) {
// if(nums.size() == 1)
// return nums[0];
// else if(nums.size() == 2){
// return max(nums[0], nums[1]);
// }else{
// vector<int> temp(nums.begin()+2, nums.end());
// vector<int> temp1(nums.begin()+1, nums.end());
// return max(nums[0] + rob(temp), rob(temp1));
// }
// return -1;
// }
int rob(vector<int>& nums) {
if(nums.size() == 0){
return 0;
}
else if(nums.size() == 1){
return nums[0];
}
else if(nums.size() == 2){
return max(nums[0], nums[1]);
}
else if(nums.size() == 3){
return max(nums[0]+nums[2], nums[1]);
}
else{
vector<int> sum(nums.size());
sum[0] = nums[0];
sum[1] = nums[1];
sum[2] = nums[0]+nums[2];
for(int index = 3; index < nums.size(); ++index){
sum[index] = max(sum[index-2], sum[index-3]) + nums[index];
}
return max(sum.back(), *(sum.end()-2));
}
return -1;
}
};
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
class Solution {
public:
int rob(vector<int>& nums) {
int siz = nums.size();
if(siz == 0) return 0;
if(siz == 1) return nums[0];
vector<int> result;
result.push_back(nums[0]);
result.push_back(nums[1]);
int max_val = nums[0];
for(int i = 2; i < siz; i++){
result.push_back(max_val+nums[i]);
max_val = max(max_val, result[i-1]);
}
return max(result[siz-2], result[siz-1]);
}
};
改进版:
Runtime: 4 ms, faster than 100.00% of C++ online submissions for House Robber.
Memory Usage: 8.5 MB, less than 100.00% of C++ online submissions for House Robber.
class Solution {
public:
int rob(vector<int>& nums) {
int siz = nums.size();
if(siz == 0) return 0;
if(siz == 1) return nums[0];
if(siz == 2) return max(nums[0], nums[1]);
if(siz == 3) return max(nums[0]+nums[2], nums[1]);
vector<int> result;
result.push_back(nums[0]);
result.push_back(nums[1]);
result.push_back(nums[0]+nums[2]);
for(int i = 3; i < siz; i++){
result.push_back(max(result[i-3], result[i-2]) + nums[i]);
}
return max(result[siz-2], result[siz-1]);
}
};