题目:
You are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed. All houses at this place are arranged in a circle. That means the first house is the neighbor of the last one. Meanwhile, adjacent houses have security system connected and it will automatically contact the police if two adjacent houses were broken into on the same night.
Given a list of non-negative integers representing the amount of money of each house, determine the maximum amount of money you can rob tonight without alerting the police.
思路:
共有两种情况:偷第一家和不偷第一家。每一种情况都用【leetcode】198. House Robber算法求就行。然后取两者的最大值即可。
代码实现:
submit一次就过了。
class Solution {
public:
int rob(vector<int>& nums) {
if (nums.size() == 0){
return 0;
}
if (nums.size() == 1){
return nums[0];
}
if (nums.size() == 2){
return max(nums[0], nums[1]);
}
// 如果抢第一家
vector<int> dp(nums.size(), 0);
dp[0] = nums[0];
dp[1] = max(nums[0], nums[1]);
for (int i = 2; i < nums.size()-1; ++i){
dp[i] = max(dp[i-2] + nums[i], dp[i-1]);
}
dp[nums.size()-1] = dp[nums.size()-2];
//如果不抢第一家
vector<int> dp2(nums.size(), 0);
dp2[0] = 0;
dp2[1] = nums[1];
for (int i = 2; i < nums.size(); ++i){
dp2[i] = max(dp2[i-2] + nums[i], dp2[i-1]);
}
return max(dp[nums.size()-1], dp2[nums.size()-1]);
}
};
discuss:
// 思想:分解成两个问题:1、抢劫0~n-2;2、抢劫1~n-1。最后取二者中的最大值。
class Solution {
public:
int rob(vector<int>& nums) {
int n = nums.size();
if (n < 2) return n ? nums[0] : 0;
return max(robber(nums, 0, n - 2), robber(nums, 1, n - 1));
}
private:
int robber(vector<int> &nums, int l, int r){
int pre = 0, cur = 0;
for (int i = l; i <= r; ++i){
int temp = max(pre + nums[i], cur);
pre = cur;
cur = temp;
}
return cur;
}
};