###### tags: `Leetcode` `medium` `dynamic programming` `python` `c++`
# 213. House Robber II
## [題目連結:] https://leetcode.com/problems/house-robber-ii/description/
## 題目:
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 a security system connected, and **it will automatically contact the police if two adjacent houses were broken into on the same night**.
Given an integer array nums representing the amount of money of each house, return the maximum amount of money you can rob tonight **without alerting the police**.
**Example 1:**
```
Input: nums = [2,3,2]
Output: 3
Explanation: You cannot rob house 1 (money = 2) and then rob house 3 (money = 2), because they are adjacent houses.
```
**Example 2:**
```
Input: nums = [1,2,3,1]
Output: 4
Explanation: Rob house 1 (money = 1) and then rob house 3 (money = 3).
Total amount you can rob = 1 + 3 = 4.
```
**Example 3:**
```
Input: nums = [1,2,3]
Output: 3
```
## 解題想法:
* 同概念基本題: [198. House Robber](/YIzmiuAqRfm6voICu36IXg)
* 此題目為: 小偷要搶錢,但是不能連續搶鄰居,且房屋頭尾視為相鄰,求能搶的最大值
* 分成兩個子問題:
* max(搶 0~n-2間 , 搶 1~n-1間)
## Python:
``` python=
class Solution(object):
def rob(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
if len(nums)<2:
return nums[0]
return max(self.robMoney(nums[:-1]),self.robMoney(nums[1:]))
def robMoney(self,nums):
if len(nums)<2:
return nums[0]
dp=[0]*len(nums)
dp[0]=nums[0]
dp[1]=max(nums[0],nums[1])
for i in range(2,len(nums)):
dp[i]=max(dp[i-1],nums[i]+dp[i-2])
return dp[-1]
result = Solution()
nums = [1,2,3,1]
ans = result.rob(nums)
print(ans)
```
## C++:
``` cpp=
class Solution {
public:
int rob(vector<int>& nums) {
if (nums.size()<2)
return nums.empty()? 0: nums[0];
return max(robMoney(nums,0,nums.size()-1), robMoney(nums,1,nums.size()));
}
int robMoney(vector<int>&nums, int start, int end){
if (end-start<2)
return nums[start];
vector<int> dp(end,0);
dp[start]=nums[start];
dp[start+1]=max(nums[start],nums[start+1]);
for (int i=start+2; i<end; i++){
dp[i]=max(dp[i-1], dp[i-2]+nums[i]);
}
return dp.back();
}
};
```