刷题笔记:动态规划实例——打家劫舍

题目链接:

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).

posted @ 2022-03-22 10:20  阿豆23  阅读(42)  评论(0)    收藏  举报