# [213. House Robber II](https://leetcode.com/problems/house-robber-ii/) # 思路 这道题是198.House Robber拓展,现在房子排成了一个圆圈,则如果抢了第一家,就不能抢最后一家,因为首尾相连了。 此题的关键点就在于:如果把第一家和最后一家分别去掉,各算一遍能抢的最大值,两个值较大的一个即为所求。 知道了这个关键点后此题就和198题没有任何区别了,198有两个思路,所以此题也有两种思路,时间复杂度均为O(n),空间复杂度均为O(1), 详见[198题解](https://github.com/ShusenTang/LeetCode/blob/master/solutions/198.%20House%20Robber.md),这里直接给出代码。 # C++ ## 思路一 ``` C++ class Solution { private: int rob_helper(vector& nums, int start, int end){ if(start > end) return 0; if(start == end) return nums[end]; int tmp, dp1 = nums[start], dp2 = max(nums[start], nums[start + 1]); for(int i = 2; i < end - start + 1; i++){ tmp = dp2; dp2 = max(dp2, nums[start + i] + dp1); dp1 = tmp; } return dp2; } public: int rob(vector& nums) { int n = nums.size(); if (n <= 1) return nums.empty() ? 0 : nums[0]; return max(rob_helper(nums, 0, n - 2), rob_helper(nums, 1, n - 1)); } }; ``` ## 思路二 ``` C++ class Solution { private: int rob_helper(vector &nums, int left, int right) { int rob = 0, notRob = 0; for (int i = left; i <= right; i++) { int preRob = rob, preNotRob = notRob; rob = preNotRob + nums[i]; notRob = max(preRob, preNotRob); } return max(rob, notRob); } public: int rob(vector& nums) { int n = nums.size(); if (n <= 1) return nums.empty() ? 0 : nums[0]; return max(rob_helper(nums, 0, n - 2), rob_helper(nums, 1, n - 1)); } }; ```