一、题目
你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。
给定一个代表每个房屋存放金额的非负整数数组,计算你 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。
示例 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 。
提示:
0 <= nums.length <= 100
0 <= nums[i] <= 400
二、思路
一开始看到题目,我还以为很简单,既然不能挨家挨户的偷,那间隔开一个就行了,所以我以为max(sum[1,3,5,…], sum[2,4,6,…])这样就可以。结果当然是错误的了,我没有考虑到不能挨着不仅仅意味着间隔为1,而是间隔>1就行。然后我就没有任何思路了。。。 。。。
通过看解析,学到了解这道题的思路,就是不从整体的角度看,从头开始,只考虑你面前的房子怎么偷要不要偷利润最大,来挨个找规律:(将这个规律放入新数组,最后一个就是答案)
- 只有一家,那第一家:肯定偷 dp[0]=nums[0]
- 有两家,肯定相邻,那偷:max(第1家,第2家) dp[1]=max(nums[0],nums[1])
- 有三家,考虑第三家要不要偷:3.1 偷,那么第二家相邻不能偷,偷的是间隔的1和3:nums[2]+nums[1]可以换成第n家加上前n-2家最大的。
3.2不偷,那么第二家就不相邻,可以偷,且只能偷第二家:nums[2]可以说成前n-1家最大的 - 有四家:考虑第四家要不要偷:4.1偷,用第n家加上前n-2家最大的 来写:dp[n-2]+nums[n] 4.2 不偷,用第n家加上前n-2家最大的 来写:dp[n-1]
- 。。。 。。。
三、代码:有了思路整个代码就好写了,不多赘述,直接看。
class Solution:
def rob(self, nums: List[int]) -> int:
if len(nums)==0:
return 0
elif len(nums)==1:
return nums[0]
dp=[0]*len(nums)
dp[0]=nums[0]
dp[1]=max(nums[0],nums[1])
for i in range(2,len(nums)):
dp[i]=max(dp[i-2]+nums[i],dp[i-1])
return dp[len(nums)-1]