这个题主要解法和1是一样的,都是动态规划,建立一个2xn的二维数组,一行表示偷,一行表示不偷。
递推公式:
i号房子偷,那么i-1号房子必不能偷,i号房子不偷,则当前最大金额值为偷到i-1号房子时偷和不偷的最大值
当前房子选择偷:dp[1][i] = dp[0][i-1]
当前房子不偷:dp[0][i] = max(dp[0][i-1],dp[1][i-1])
那么max(dp[0][n-1],dp[1][n-1])就是答案
此题与之不同的是,最后一个房子和第一个房子接上了,围成了一圈。
分析:
围成圈,并不影响到内部房子,仅仅影响了第一个房子和最后一个房子。
也就是说,第一个房子如果被偷了,那么最后一个房子就不能偷了。
乍一看,我们上面的式子,并没有明确保留某一间房子偷还是没偷的信息。
但实际上,我们上面去得到偷取的最大金额,并不在乎某一个房子偷没偷,仅仅在乎是在哪一个区间去偷。
这样就很好办了,直接搜两次,一次范围为[0, (n-1) -1],另一次范围为[1,n-1]
class Solution {
int stolen(vector<int>& nums,int start,int end)
{
int n = nums.size();
vector<vector<int>> dp(2,vector<int>(n));
dp[0][start] = 0;
dp[1][start] = nums[start];
for(int i = start+1; i < end; ++i)
{
dp[0][i] = max(dp[1][i-1],dp[0][i-1]);
dp[1][i] = dp[0][i-1]+nums[i];
}
return max(dp[0][end-1],dp[1][end-1]);
}
public:
int rob(vector<int>& nums) {
int n = nums.size();
if(n==0) return NULL;
if(n==1) return nums[0];
return max(stolen(nums,0,n-1),stolen(nums,1,n));
}
};
T.T,想不到,只能记住了。