• 【每日一题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)
  • 相关阅读:
    神经网络控制法的工作原理,什么是神经网络控制
    知识问答之初步入门-2
    kafka客户端应用参数详解
    C++5-explicit、const的用法、mutable、常成员函数构成重载、在主函数中修改m_i的值
    bash: redi-cli: 未找到命令...
    秋招刷题4(动态规划)
    【cmake实战七】如何使用编译的库(动态库dll)2——windows系统
    【中秋佳节】CSDN卷王们内卷--中秋节要不要休息呢?
    时代变了,199 美元的 iPhone 都可以想了?
    jmh测试实践(针对不同准备数据测试)
  • 原文地址:https://blog.csdn.net/Tikitian/article/details/132917674