这道题的题解采用了递归加备忘录的方法来求解。小偷有一个选择,他可以选择从当前的房子开始偷或者跳过一两个房子后再开始偷。基本的递归策略是:考虑当前位置c,小偷可以选择偷这个房子然后跳过下一个,直接从c+2开始或者从c+3开始(即不偷当前房子,也可能不偷下一个,但考虑后一个),或者不偷当前房子直接从c+1开始。结果是这些选择中可以偷到的最大金额。使用备忘录(cache)来存储已经计算过的结果,避免重复计算,提高效率。
时间复杂度: O(n)
空间复杂度: O(n)
from typing import List
# Solution class to solve the problem
class Solution:
def rob(self, nums: List[int]) -> int:
# Cache to store the results of subproblems
cache = {}
# Helper function to perform depth-first search
def dfs(nums, c, money):
n = len(nums)
# Base cases to handle the last one or two houses
if c == n-1 or c == n-2: return nums[c]
# Return negative if index is out of bounds
elif c >= n: return -1
# Use cached value if available
if c in cache: return cache[c]
# Calculate the maximum money from current house and two options ahead
res = [dfs(nums, c+1, money), dfs(nums, c+2, money) + nums[c], dfs(nums, c+3, money) + nums[c]]
# Determine the maximum value and index
max_i = max(enumerate(res), key=lambda x: x[1])
# Store the result in cache and return
cache[c] = max_i[1]
return max_i[1]
# Initial conditions for arrays of length 1 and 2
if n == 1: return(nums[0])
if n == 2: return(max(nums[0], nums[1]))
# Start the dfs from the first house
else: return(dfs(nums, 0, 0))