1. 题目描述
213. 打家劫舍 II
你是一个专业的小偷,计划偷窃沿街的房屋,每间房内都藏有一定的现金。这个地方所有的房屋都 围成一圈 ,这意味着第一个房屋和最后一个房屋是紧挨着的。同时,相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警 。
给定一个代表每个房屋存放金额的非负整数数组,计算你 在不触动警报装置的情况下 ,能够偷窃到的最高金额。
示例 1:
输入:nums = [2,3,2]
输出:3
解释:你不能先偷窃 1 号房屋(金额 = 2),然后偷窃 3 号房屋(金额 = 2), 因为他们是相邻的。
示例 2:
输入:nums = [1,2,3,1]
输出:4
解释:你可以先偷窃 1 号房屋(金额 = 1),然后偷窃 3 号房屋(金额 = 3)。
偷窃到的最高金额 = 1 + 3 = 4 。
示例 3:
输入:nums = [0]
输出:0
提示:
1 <= nums.length <= 100
0 <= nums[i] <= 1000
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/house-robber-ii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
2.代码如下
int max(int a,int b)
{
return a>b?a:b;
}
int robsingle(int *nums,int left,int right)
{
if (right-left <= 1)
{
nums[left];
}
int dp[200] = {0};
dp[left] = nums[left];
dp[left+1] = max(nums[left],nums[left+1]);
for (int i = left+2;i <= right;++i)
{
dp[i] = max(dp[i-1],nums[i] + dp[i-2]);
}
return dp[right];
}
int rob(int* nums, int numsSize){
if (numsSize <= 0)
{
return 0;
}
if (numsSize == 1)
{
return nums[0];
}
if (numsSize == 2)//首尾相接,只抢一家
{
return max(nums[0],nums[1]);
}
int start1 = 1;
int n1 = numsSize-1;
int start2 = 0;
int n2 = numsSize-2;
return max(robsingle(nums,start2,n2),robsingle(nums,start1,n1));
}
3.思路
由于首尾相接,所以会有一个抢首不抢尾,抢尾不抢首的条件,那么,对于n个房间,从0,1,2…n-1,那么就可以分别去掉首尾来看,即,分别求0,1,2,…n-2或1,2,n-1这两种情况的最大值并取其最大即可。