zoukankan      html  css  js  c++  java
  • leetcode198之打家劫舍问题

    问题描述
    你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。
    给定一个代表每个房屋存放金额的非负整数数组,计算你 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。
     
    解析:
    dp[0]:只有一间房屋,第一天所偷结果。dp[0]=nums[0]
    dp[1]:有两间房屋,前两天所偷结果。dp[1]=max(nums[0],nums[1])
    因此dp[k]含义:前k+1天所偷结果;nums[k]含义:第k+1天所偷结果
    当第k+1天没偷时,前k+1天所偷结果为前k天所偷结果:dp[k]=dp[k-1]
    当第k+1天偷了,那么第k天一定没偷,前k+1天所偷结果为前k-1天所偷结果与第k+1天所偷结果之和:dp[k]=dp[k-2]+nums[k]
     
    综上所述,这是一个动态规划问题,找出边界条件
    当只有一间房屋时,所偷金额最大值即为dp[0]=nums[0]
    当有两间房屋时,所偷金额最大值为dp[1]=max(nums[0],nums[1])
     
    因为依次遍历数组,在数组最后一个元素处即可得出最大值,所以最终答案为dp[n-1](前n天所偷结果),n为数组长度。
     
    代码如下:
     
     1 # 打家劫舍问题
     2 def rob(nums):
     3     '''
     4 
     5     :param nums:
     6     :return:
     7     '''
     8     size = len(nums)
     9     dp = [0] * size
    10 
    11     if size == 0:
    12         return 0
    13 
    14     if size == 1:
    15         return nums[0]
    16 
    17     dp[0] = nums[0]
    18     dp[1] = max(nums[0], nums[1])
    19 
    20     for i in range(2, size):
    21         dp[i] = max(dp[i - 2] + nums[i], dp[i - 1])
    22 
    23     return dp[size - 1]

    需要注意的特殊情况:

    当房屋数为0时,即数组为空数组时,此时应加额外条件进行判断,返回值为0;当房屋数为1时,为两者中最大值

    复杂度分析:

    时间复杂度:因为遍历了一遍数组,所以时间复杂度为O(n),n为数组长度

    空间复杂度:O(1)。使用滚动数组,存储的是当前房屋的前两间房屋的最大值,而不需要存储整个数组,因此空间复杂度为O(1)

     
     
  • 相关阅读:
    PHP入门03 -- 数组与数据结构
    PHP入门02 -- 函数
    PHP入门01 -- 基本语法
    node文章
    Mongodb08
    Mongodb07
    ISO处理jq事件
    map
    Django自定义模板
    JS this指向
  • 原文地址:https://www.cnblogs.com/rounie/p/12989378.html
Copyright © 2011-2022 走看看