打家劫舍 II
你是一个专业的小偷,计划偷窃沿街的房屋,每间房内都藏有一定的现 金。这个地方所有的房屋都围成一圈,这意味着第一个房屋和最后一个房屋是紧挨着的。同时,相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。
给定一个代表每个房屋存放金额的非负整数数组,计算你在不触动警报装置的情况下,能够偷窃到的最高金额。
示例 1:
输入: [2,3,2]
输出: 3
解释: 你不能先偷窃 1 号房屋(金额 = 2),然后偷窃 3 号房屋(金额 = 2), 因为他们 是相邻的。
示例 2:
输入: [1,2,3,1]
输出: 4
解释: 你可以先偷窃 1 号房屋(金额 = 1),然后偷窃 3 号房屋(金额 = 3)。
偷窃到的最高金额 = 1 + 3 = 4 。
看问题,作为小偷
对 第 i 家 ,仅仅两种操作 1. 偷 2.不偷
则:
设maxPro(i) 为小偷到第i 家的最大收获
1.偷 a[i-1] 和 maxPro(i-2) 之和
2.不偷 maxPro(i-1)
边界问题
可以显然做出决策的情况:
1.当只有1家 即 maxPro(i) = a[0] 直接偷
2.当有2家 即 maxPro(i) = max(a[0],a[1]); 取最大
问题:
当然,这里是三家,也可以直接得出,max(a[0],a[1],a[2]),但是为什么n == 3不是边界条件?
自然是 当n等于 3 的时候呢,已经可以由 上述的规律推出,当然这也恰好说明了一些情况下的边界:
防止数组越界的所确定的值
class Solution {
public:
int rob(vector<int>& nums) {
const int n = nums.size();
int* maxSum =new int[n+1];
int ans(0);
for(int i = 0;i<n;++i)
{
int& d = maxSum[i];
if(i == 0) d = nums[0];
else if(i == 1) d = max(nums[0],nums[1]);
else
d = max(maxSum[i-1],maxSum[i-2]+nums[i]);
if(d>ans) ans = d;
}
return ans;
}
};
这个有点怪,同样的代码,一直越界,最后 让 d 引用 maxSum 就过了,害,还是 引用 好,又能节省代码,还能 过,推荐引用。