leetcode 打家劫舍II 中等_编程题

 

 

dp[i][0] 表示前 i 个数不偷 i 位置的最大和,dp[i][1] 表示前 i 个数偷 i 位置的最大和

然后这个题是首尾相连的,所以,做两次 dp 就行,两次 dp 的下标范围为 [0, size - 2] 与 [1, size - 1]

class Solution {
public:
    int rob(const vector<int>& nums) {
        if(nums.empty()) return 0;
        if(nums.size() == 1) return nums[0];  // 注意 size() 为 1 特殊处理
        return max(dpWithLR(nums, 0, nums.size() - 1), dpWithLR(nums, 1, nums.size()));
    }

private:
    int dpWithLR(const vector<int>& nums, int l, int r) {
        int dp[2][2] = {0};   // 0 表示不包含 i, 1 表示包含 i
        dp[l & 1][1] = nums[l];
        for(int i = l + 1; i < r; ++ i) {
            dp[i & 1][0] = max(dp[(i - 1) & 1][0], dp[(i - 1) & 1][1]);
            dp[i & 1][1] = dp[(i - 1) & 1][0] + nums[i];
        }
        return max(dp[(r - 1) & 1][1], dp[(r - 1) & 1][0]);
    }
};