代码随想录算法训练营第42天 | 动态规划7:打家劫舍入门
打家劫舍
https://leetcode.cn/problems/house-robber/description/
代码随想录
https://programmercarl.com/0198.打家劫舍.html
打家劫舍-环形
https://leetcode.cn/problems/house-robber-ii/description/
代码随想录
https://programmercarl.com/0213.打家劫舍II.html#思路
打家劫舍-树形
https://leetcode.cn/problems/house-robber-iii/description/
https://programmercarl.com/0337.打家劫舍III.html#其他语言版本
打家劫舍
理论
- 特点:相邻房间不能访问;
- 动态规划模版
- dp数组:dp[i] dp[i]间房子内 最多可以偷到的金额是多少;
- 递推公式:第i间 房间偷不偷;
- 偷上上一间和本间:dp[i-2]+nums[i]
- 偷上一间:dp[i-1]
- 初始化:dp[0] = nums[0] dp[1] = max(nums[0],nums[1])
题解代码
class Solution:
def rob(self, nums: List[int]) -> int:
if len(nums)==1:
return nums[0]
if len(nums) == 0:
return 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-1],dp[i-2]+nums[i])
return dp[-1]
打家劫舍-环形
题解思路
- 思考限制
- 前后不能同时选
1.选0 不选-1
2.选-1 不选0
3.都不选
情况1.2都包括情况3 所以不考虑情况3 分类讨论情况2即可
- 前后不能同时选
题解代码
点击查看代码
class Solution:
def thef(self,nums):
if len(nums)==1:
return nums[0]
if len(nums) == 0:
return 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-1],dp[i-2]+nums[i])
return dp[-1]
def rob(self, nums: List[int]) -> int:
if len(nums)==1:
return nums[0]
if len(nums)==0:
return 0
rob_1 = self.thef(nums[:-1])
rob_2 = self.thef(nums[1:])
return max(rob_1,rob_2)
打家劫舍-树形DP
题解思路
- dp[0][1]
dp[0] 不选该root 继承子树和的最大值;
dp[1] 选该root,不选左右子树的和;
最终结果为两个值中的max - 后序遍历
- 终止条件:空节点;
点击查看代码
class Solution:
def trans(self,root):
if not root:
return (0,0)
left = self.trans(root.right)
right = self.trans(root.left)
val_0 = max(left)+max(right)
val_1= root.val + left[0]+right[0] ##0是没选自己
return (val_0,val_1)
def rob(self, root: Optional[TreeNode]) -> int:
res = max(self.trans(root))
return res
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?