今天还是dp题(horse robber系列),主要想清楚递推公式就行
198. House Robber
还是按照5步去做,dp[i]代表到i为止最多能rob多少.递推公式涉及到两种情况,一种是当前house偷,还有一种是当前house不偷.初值0赋值house0的值,初值1赋值house0和1之间最大的,剩下的dp就行了
class Solution:
def rob(self, nums: List[int]) -> int:
if len(nums)==1:
return nums[0]
if len(nums)==2:
return max(nums)
dp=[0 for _ in range(len(nums))]
dp[0]=nums[0]
dp[1]=max(nums[1],nums[0])
for i in range(2,len(nums)):
dp[i]=max(dp[i-1],dp[i-2]+nums[i])
return dp[-1]
213. House Robber II
这道题就是在第一道题基础上拆分就行了.如果要拆圆则需要囊括三种情况,一种是抛弃最后一个房子,一个是抛弃第一个房子,一个是第一个和最后一个都抛弃.但是实际上对于dp来说前面两种都已经包括最后一种了,所以只要把前两种都求出来,然后比较大小即可
class Solution:
def rob(self, nums: List[int]) -> int:
def hr(tmp):
dp=[0 for _ in range(len(tmp))]
dp[0]=tmp[0]
dp[1]=max(tmp[1],tmp[0])
for i in range(2,len(tmp)):
dp[i]=max(dp[i-1],dp[i-2]+tmp[i])
return dp[-1]
if len(nums)<3:
return max(nums)
return max(hr(nums[1:]),hr(nums[:-1]))
337. House Robber III
这道题是树上rob.基本思路就是如果把dp和dfs进行结合.首先是从leaf推到root所以一定是后序遍历.其次每次只要更新最小值和最大值就行了.
class Solution:
def rob(self, root: Optional[TreeNode]) -> int:
def dfs(node):
if not node:
return (0,0)
left=dfs(node.left)
right=dfs(node.right)
val_0 =max(left)+max(right)
val_1=node.val+left[0]+right[0]
return (val_0,val_1)
dp=dfs(root)
return max(dp)