Solution 1
一个变体的背包问题。需要保证转移是前一个间隔状态。
状态转移思路:来自前一个状态(当前不选择),或者前一个间隔状态和当前状态的加和(当前选择)
状态转移方程为: d p [ i ] = max ( d p [ i − 1 ] , d p [ i − 2 ] + n u m [ i ] ) dp[i] = \max (dp[i - 1], dp[i - 2] + num[i]) dp[i]=max(dp[i−1],dp[i−2]+num[i])
不过考虑到整个过程中只需要维护最新的两个状态,因此可以简化上述结果的储存过程
- 时间复杂度: O ( n ) O(n) O(n),其中 n n n为输入的长度
- 空间复杂度: O ( 1 ) O(1) O(1),仅维护常数个状态量
class Solution {
public:
int rob(vector<int>& nums) {
if (nums.size() <= 1) {
// 从1判定比较方便
return nums.size() == 0? 0: nums[0];
}
// vector<int> ans = {nums[0], max(nums[0], nums[1])};
// for (int i = 2; i < nums.size(); ++i) {
// ans.push_back(max(ans[i - 1], ans[i - 2] + nums[i]));
// }
// return ans[nums.size() - 1];
int first = nums[0], second = max(nums[0], nums[1]);
for (int i = 2; i < nums.size(); ++i) {
int temp = second;
second = max(second, first + nums[i]);
first = temp;
}
return second;
}
};
Solution 2
Solution 1的Python实现
class Solution:
def rob(self, nums: List[int]) -> int:
if len(nums) <= 1:
return 0 if len(nums) == 0 else nums[0]
first, second = nums[0], max(nums[0], nums[1])
for i in range(2, len(nums)):
temp = second
second = max(second, first + nums[i])
first = temp
return second