题目:
你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。
给定一个代表每个房屋存放金额的非负整数数组,计算你在不触动警报装置的情况下,能够偷窃到的最高金额。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/house-robber
采用了两种方法,
- solution1 采用的是递归的方式,从数组的最后两位开始,如果选择最后一个,则在nums[:n - 2]寻找最大偷窃额度, 如果选择倒数第二个,则在num[:n-3]中寻找一个最大偷窃额度。但是solution1在leetcode超出了时间限制。
def solution1(nums):
max_mony = 0
n = len(nums)
if n == 0:
return max_mony
if n == 1:
max_mony += nums[0]
return max_mony
if n == 2:
max_mony += max(nums)
return max_mony
if n == 3:
max_mony += max(nums[0]+nums[2], nums[1])
return max_mony
if n > 3:
max_mony = max(nums[n-1] + solution(nums[:n - 2]), nums[n - 2] + solution(nums[:n - 3]))
return max_mony
max_mony = max(nums[n-1] + solution(nums[:n - 2]), nums[n - 2] + solution(nums[:n - 3]))
其中的max(f1, f2),f2可以优化成solution(num[:n-1]),相当于在除去最后一项xuan
- solution2 动态规划的方式,从数组正向开始,只需两个变量premax与currmax去更新,pre记录的相当于是前数组当前位置前两个的元素,可以自己推算一下。currmax是当前的最大值。
def solution2(nums):
'''
'''
premax = 0
currmax = 0
for i in nums:
temp = currmax
currmax = max(i + premax, currmax)
premax = temp
return currmax
测试代码如下:
def solution1(nums):
max_mony = 0
n = len(nums)
if n == 0:
return max_mony
if n == 1:
max_mony += nums[0]
return max_mony
if n == 2:
max_mony += max(nums)
return max_mony
if n == 3:
max_mony += max(nums[0]+nums[2], nums[1])
return max_mony
if n > 3:
#while i>=4
max_mony = max(nums[n-1] + solution(nums[:n - 2]), nums[n - 2] + solution(nums[:n - 3]))
return max_mony
def solution2(nums):
'''
'''
premax = 0
currmax = 0
for i in nums:
temp = currmax
currmax = max(i + premax, currmax)
premax = temp
return currmax
if __name__ == "__main__":
#nums = [1,2,3,1]
nums = [2,7,9,3,1]
mony = solution2(nums)
print(mony)