1.题目解析
题目来源:LCR.090.打家劫舍——力扣
测试用例
2.算法原理
1.状态表示
每一个房子都有两个状态:被偷与不被偷,因此需要两个dp表f/g来表示被偷与不被偷,其中f[i]/g[i]表示小偷走到第i个位置的最大偷钱数
2.状态转移方程
第i个位置被偷时i-1个位置一定不被偷,则求出g[i-1]+nums[i]就是f[i];第i个位置不被偷则第i-1个位置可以被偷也可以不被偷,取二者较大值即可
由于房子是一个环形并且小偷不能连续偷两个相邻的房子,因此我们可以分类讨论将环形变为两个区间。
第一种情况:第一个房子被偷:此时第二个房子与最后一个房子一定不被偷,则只需要在第三个房子与倒数第二个房子的区间判断最大偷钱数即可
第二种情况:第一个房子不被偷:此时计算第二个房子到最后一个房子的区间内的最大偷钱数即可
3.实战代码
class Solution {
public:
int cycle(vector<int>& nums, int left, int right) {
if (left > right) {
return 0;
}
int n = nums.size();
vector<int> f(n);
vector<int> g(n);
f[left] = nums[left];
for (int i = left + 1; i <= right; i++) {
f[i] = g[i - 1] + nums[i];
g[i] = max(f[i - 1], g[i - 1]);
}
return max(f[right], g[right]);
}
int rob(vector<int>& nums) {
int n = nums.size();
return max(nums[0] + cycle(nums, 2, n - 2), cycle(nums, 1, n - 1));
}
};