刷题笔记:动态规划实例——打家劫舍
题目链接:
https://leetcode-cn.com/problems/house-robber/
按照基本逻辑走:
1,确定状态
首先分析题目,找核心逻辑。本题中规定不能获得相邻位置的数据,同时可以容易想到,越到后面,累加值越大。
由此我们遇到一个问题,最后取第n个数据,还是取第n-1个数据呢?
只需要比较一下前n个能取得的最大和与前n-1个能取到的最大和,谁大取谁。
此处可以使用一个数组d存储对应第i个位置能取得的最大和;
2,找到转移公式
比较第n个与第n-1个,将转换为比较第n-2个与个n-3个。
由此可以得到转移公式:d[i]=max(d[i-2]+nums[i},d[i-1])。
3,确定初始条件以及边界条件
显然第一个数据与第二个数据,只有一种可能,因此为边界条件。
4,计算结果。
class Solution {
public:
int rob(vector<int>& nums) {
int len=nums.size();
if(len==1) return nums[0];//当只有一个数据时,它就是最大和
int lis[len];//辅助数组,表示当前位置能获得的最大值
lis[0]=nums[0];//初始化边界
lis[1]=max(nums[0],nums[1]);
for(int i=2;i<len;i++)//当有三个及以上数据时开始循环
{
lis[i]=max(nums[i]+lis[i-2],lis[i-1]);//转移公式
}
return lis[len-1];//返回最后的数据
}
};
5.优化代码
从上面代码中可以发现,辅助数组其实不是必要的,每次只需要使用最后的位置,以及它前面的两个位置,所有使用3个变量即可,空间复杂度可以降为常数级O(1).

浙公网安备 33010602011771号