文章目录
一、题目
二、我的解法:动态规划
2.1 题目分析
本题若使用暴力遍历求解,有 n 个元素,每个元素有 偷窃/不偷窃 两张状态,则时间复杂度为 O(2n),因此不能使用暴力求解法。
这种涉及到重复计算的问题,一般思路是把需要重复使用的值先保存下来,后续就可以直接使用。考虑使用动态规划算法(dp):
定义状态 f(i) 为遍历到第 i 个房屋时偷窃到的最高金额,则状态转移方程为:
若偷窃第 i 个房屋,则不偷窃第 i-1 个房屋:f1(i)=f(i-2)+nums[i], n>=2
若不偷窃第 i 个房屋: f2(i)=f(i-1), n>=2
则 f(i)=max(f1(i),f2(i))
初始状态为 f(0)=nums[0], f(1)=max(nums[0],nums[1])
最终能够偷窃到的最高金额为 max(f(i))=f(-1)
2.2 code
class Solution:
def rob(self, nums: List[int]) -> int:
length=len(nums)
if length==0:
return 0
if length==1:
return nums[0]
if length==2:
return max(nums[0],nums[1])
# 初始化 dp 数组和初始状态
dp=[0]*length
dp[0]=nums[0]
dp[1]=max(nums[0],nums[1])
# 状态转移
for i in range(2,length):
dp[i]=max(dp[i-2]+nums[i],dp[i-1])
return dp[-1]
目前看到最好的方法就是 dp 了,这道题也是一道典型的适合用 dp 的题目了。关于 dp 一些经典题目的讲解可以参考视频 《算法零基础入门》动态规划