• 40-设计问题-最小栈


    原题链接:

    198. 打家劫舍

    题目描述:

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

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

    数据范围: 

    • 1 <= nums.length <= 100
    • 0 <= nums[i] <= 400

    测试样例:

    示例 1:

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

    示例 2:

    输入:[2,7,9,3,1]
    输出:12
    解释:偷窃 1 号房屋 (金额 = 2), 偷窃 3 号房屋 (金额 = 9),接着偷窃 5 号房屋 (金额 = 1)。
         偷窃到的最高金额 = 2 + 9 + 1 = 12 。
    

    思路:二维动态规划

    对于每一家而言,都有 偷了 没偷 这两种状态,所以可以用一个二维 dp 数组(共 2 行 n 列)来表示某一家是否被偷。顺序遍历原数组,模拟小偷从第一家偷到最后一家的过程。那么有 dp[0][i] 表示小偷走到索引为 i 的那一家,但是没偷他们家时获得的最大金额;相应的 dp[1][i] 表示小偷走到索引为 i 的那一家,并且偷了他们家时获得的最大金额。因为被偷的两家不能相邻,所以可以得到递推关系:dp[0][i] = max(dp[0][i-1], dp[1][i-1])因为 dp[0][i] 表示没有偷这一家所以偷没偷前面的一家无所谓,返回二者中的最大值dp[1][i] = dp[0][i-1] + nums[i]因为 dp[1][i] 表示偷了这一家所以前一家必定不能偷,只能是 dp[0][i-1] 但是又因为偷了当前这个一家收益还要增加 nums[i]。并且可以得到初始值分别为 dp[0][0] = 0 和 dp[1][0] = nums[0]。仔细思考一下发现不重复不遗漏,那么最终的结果就是小偷走到最后一家时的最大收益 max(dp[0][n-1], dp[1][n-1])

    代码:

    1. class Solution {
    2. public:
    3. int rob(vector<int>& nums) {
    4. int n = nums.size();
    5. int dp[2][n];
    6. dp[0][0] = 0, dp[1][0] = nums[0];
    7. for (int i = 1; i < n; i ++) {
    8. dp[0][i] = max(dp[0][i-1], dp[1][i-1]);
    9. dp[1][i] = dp[0][i-1] + nums[i];
    10. }
    11. return max(dp[0][n-1], dp[1][n-1]);
    12. }
    13. };

    复杂度:

    时间复杂度:

    遍历了一遍整个数组

    时间复杂度为 O(N)

    空间复杂度:

    创建了一个辅助数组存储 dp 结果

    空间复杂度为 O(N)

  • 相关阅读:
    python中的图像增强技术
    从一线撤回二三线城市的程序员们,最后都怎么样了?
    基于ssm的贫困生管理系统javaEE
    unity工程参照以及评价(B)
    rails常用小技巧合集(一)
    华为OD机试 - 考勤信息 - 双指针(Java 2023 B卷 100分)
    基于 HBase & Phoenix 构建实时数仓(1)—— Hadoop HA 安装部署
    暑期JAVA学习(43.2)反射
    uniapp解决scroll滑动之后被u-sticky挡住的问题
    CentOSt7安装Redis错误:/bin/sh: cc: 未找到命令
  • 原文地址:https://blog.csdn.net/m0_74457208/article/details/134450062