0%

LeetCode-198-打家劫舍

LeetCode 198 打家劫舍

198.打家劫舍

你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。

给定一个代表每个房屋存放金额的非负整数数组,计算你不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。

示例:

输入:[1,2,3,1]
输出:4
解释:偷窃 1 号房屋 (金额 = 1) ,然后偷窃 3 号房屋 (金额 = 3)。
偷窃到的最高金额 = 1 + 3 = 4 。

动态规划

此处是一个非常明显的动态规划问题,在物品的选取上,主要的限制在于不能选取两个相邻的物品,在此条件下实现物品价值的最大化。

  1. 动态规划数组的定义:定义数组 dp[nums.size()+1] 表示在 nums.size() 个物品中进行选取能够得到的最大的物品价值。

  2. 动态规划数组的推导:在 j 个物品中选取,可以选取第 j 个物品也可以不进行选取,那么 dp[j]=max(dp[j-1],dp[j-2]+nums[j-1])

  3. 动态规划数组的初始化:对于 dp[0] 不存在可选元素, dp[0]=0 ,对于 dp[1] 只能选取第一个元素 dp[1]=nums[0]

  4. 动态规划数组的遍历顺序:在递推的过程中使用到的前面的数据,因此从前向后遍历。

  5. 举例验证:对于 nums=[1,2,3,1]

dp={0,1,0,0,0}
dp={0,1,2,0,0}
dp={0,1,2,4,0}
dp={0,1,2,4,4}

验证正确。

此处在进行计算时,实际上只使用到了前两个元素的值,那么只需要常数的元素空间。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Solution {
public:
int rob(vector<int>& nums) {
if(nums.size()==1) return nums.front();
int n0=0,n1=nums[0];
int res;
for(int i=2;i<=nums.size();i++){
res=max(n1,n0+nums[i-1]);
n0=n1;
n1=res;
}
return res;
}
};
-------------本文结束感谢您的阅读-------------

欢迎关注我的其它发布渠道