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]); } };