leetcode198之打家劫舍问题

问题描述
你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。
给定一个代表每个房屋存放金额的非负整数数组,计算你 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。
 
解析:
首先考虑只有一间房屋情况。当只有一间房屋,偷窃最高金额即是这间房屋金额
 
当有两间房屋时,偷窃最大金额为两间房屋中的最大值
 
当房屋数在2间以上时,假设房屋k被偷,则前k间房屋所偷金额最大值为:max(dp[k-1],dp[k]+nums[k-2]);房屋k没被偷,则前k间金额最大值为dp[k-1].
 
综上所述,这是一个动态规划问题
 
如下状态转移方程
dp[i]=max(dp[i2]+nums[i],dp[i1])
边界条件为:
dp[0]=nums[0
dp[1]=max(nums[0],nums[1]) 
 
因为依次遍历数组,在数组最后一个元素处即可得出最大值,所以最终答案为dp[n-1],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)

 
 

版权声明:本文为rounie原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/rounie/p/12989378.html