Table of contents
Topic source
213. House Robbery II - LeetCode
topic description
You are a professional thief planning to rob houses along the street, each of which has a certain amount of cash hidden in it. All the houses in this place are arranged in a circle, which means that the first house and the last house are right next to each other. At the same time, adjacent houses are equipped with interconnected anti-theft systems. If two adjacent houses are broken into by thieves at the same night, the system will automatically call the police.
Given an array of non-negative integers representing the amount of money stored in each house, calculate the maximum amount you can steal tonight without setting off the alarm.
example
Example 1:
Input: nums = [2,3,2]
Output: 3
Explanation: You cannot first steal house 1 (amount = 2) and then steal house 3 (amount = 2), because they are adjacent.
Example 2:
Input: nums = [1,2,3,1]
Output: 4
Explanation: You can first steal house 1 (amount = 1) and then steal house 3 (amount = 3). Maximum amount stolen = 1 + 3 = 4.
Example 3:
Input: nums = [1,2,3]
Output: 3
hint
- 1 <= nums.length <= 100
- 0 <= nums[i] <= 1000
topic analysis
This question is LeetCode - 198 Robbery - Blogs Outside Fucheng - CSDN Blog Extension Questions
Before doing this question, you need to understand the link topic first.
The difference between this question and the linked question is that 198 Dajiajieshe is a linear array, while 213 Dajiajieshe is a circular array.
Linear array, nums[0] is selected, which has no effect on the selection of nums[nums.length-1]
Ring array, if nums[0] is selected, nums[nums.length-1] cannot be selected, because nums[0] and nums[nums.length-1] are adjacent.
Therefore, the easiest way to do this question is to untie the ring array from the beginning to the end and turn it into a linear array.
That is, the circular array can be split into two types of linear arrays,
- Discard nums[0], and the rest form a linear array
- Discard nums[nums.length - 1], and the remaining part forms a linear array
Therefore, this question is just one more step compared to 198, where the circular array is split into a linear array, and the linear array can be done directly according to 198.
JS algorithm source code
/**
* @param {number[]} nums
* @return {number}
*/
var rob = function (nums) {
if (nums.length == 1) return nums[0];
return Math.max(
stealMaxMoney(nums.slice(0, -1)),
stealMaxMoney(nums.slice(1))
);
};
function stealMaxMoney(nums) {
const n = nums.length;
const dp = new Array(n);
if (n >= 1) dp[0] = nums[0];
if (n >= 2) dp[1] = Math.max(nums[0], nums[1]);
for (let i = 2; i < n; i++) {
dp[i] = Math.max(dp[i - 1], dp[i - 2] + nums[i]);
}
return dp[n - 1];
}
House Robbery II - Submission History - LeetCode
Java algorithm source code
class Solution {
public int rob(int[] nums) {
if(nums.length == 1) return nums[0];
return Math.max(stealMaxMoney(Arrays.copyOfRange(nums, 0, nums.length - 1)), stealMaxMoney(Arrays.copyOfRange(nums, 1, nums.length)));
}
public int stealMaxMoney(int[] nums) {
int n = nums.length;
int[] dp = new int[n];
if (n >= 1) dp[0] = nums[0];
if (n >= 2) dp[1] = Math.max(nums[0], nums[1]);
for (int i = 2; i < n; i++) {
dp[i] = Math.max(dp[i - 1], dp[i - 2] + nums[i]);
}
return dp[n - 1];
}
}
House Robbery II - Submission History - LeetCode
Python algorithm source code
def stealMaxMoney(nums):
n = len(nums)
dp = [0] * n
if n >= 1:
dp[0] = nums[0]
if n >= 2:
dp[1] = max(nums[0], nums[1])
for i in range(2, n):
dp[i] = max(dp[i - 1], dp[i - 2] + nums[i])
return dp[n - 1]
class Solution(object):
def rob(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
if len(nums) == 1:
return nums[0]
return max(stealMaxMoney(nums[:-1]), stealMaxMoney(nums[1:]))