• 【每日一题Day328】LC198打家劫舍 | 动态规划


    打家劫舍【LC198】

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

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

    来源:力扣(LeetCode
    链接:https://leetcode.cn/problems/house-robber
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

    我猜明天是打家劫舍Ⅱ

    动态规划

    1. 确定dp数组(dp table)以及下标的含义

      考虑下标i(包括i)以内的房屋,最多可以偷窃的金额为dp[i]

    2. 确定递推公式

      • 偷第 i i i间房: d p [ i ] = d p [ i − 2 ] + n u m s [ i ] dp[i] = dp[i-2] + nums[i] dp[i]=dp[i2]+nums[i]
      • 不偷第 i i i间房: d p [ i ] = d p [ i − 1 ] dp[i] = dp[i-1] dp[i]=dp[i1]

      d p [ i ] = m a x ( d p [ i − 2 ] + n u m s [ i ] , d p [ i − 1 ] ) dp[i] =max( dp[i-2] + nums[i], dp[i-1]) dp[i]=max(dp[i2]+nums[i],dp[i1])

    3. dp数组如何初始化

      dp[0] = nums[0];
      dp[1] = Math.max(nums[0],nums[1]);
      
      • 1
      • 2
    4. 确定遍历顺序

      从前往后遍历nums

    5. 举例推导dp数组

      • 代码

        class Solution {
            public int rob(int[] nums) {
                if (nums.length == 1){
                    return nums[0];
                }
                if (nums.length == 2){
                    return Math.max(nums[0],nums[1]);
                }
                int[] dp = new int[nums.length];
                dp[0] = nums[0];
                dp[1] = Math.max(nums[0],nums[1]);
                for (int i = 2; i < nums.length; i++){
                    dp[i] = Math.max(dp[i-2] + nums[i],dp[i-1]);
                }
                return dp[nums.length-1];
            }
        }
        
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
        • 7
        • 8
        • 9
        • 10
        • 11
        • 12
        • 13
        • 14
        • 15
        • 16
        • 17
        • 复杂度

          时间复杂度: O ( n ) O(n) O(n)

          空间复杂度: O ( n ) O(n) O(n)

    • 优化

      class Solution {
          public int rob(int[] nums) {
              if (nums.length == 1){
                  return nums[0];
              }
              if (nums.length == 2){
                  return Math.max(nums[0],nums[1]);
              }
              int[] dp = new int[2];
              dp[0] = nums[0];
              dp[1] = Math.max(nums[0],nums[1]);
              for (int i = 2; i < nums.length; i++){
                  dp[i % 2] = Math.max(dp[(i - 2) % 2] + nums[i],dp[(i - 1) % 2]);
              }
              return Math.max(dp[0], dp[1]);
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 复杂度
        • 时间复杂度: O ( n ) O(n) O(n)
        • 空间复杂度: O ( 1 ) O(1) O(1)
  • 相关阅读:
    浅谈C++|STL之string篇
    IgH Master环境搭建
    【K8S系列】第十讲:kubectl 命令大全
    全新UI简洁又不失美观的短视频去水印微信小程序源码,支持多做流量主模式
    docker快速建立samba、vsftp文件共享
    【Spring】AOP进阶-JoinPoint和ProceedingJoinPoint详解
    vue3【echarts 做的词云图】
    密码学系列4-选择密文安全,同态加密安全性
    1786_MTALAB代码生成把通用函数生成独立文件
    一文彻底搞懂cookie与session
  • 原文地址:https://blog.csdn.net/Tikitian/article/details/132917674