dp[i]:考虑下标i(包括i)以内的房屋,最多可以偷窃的金额为dp[i]。
考虑i:dp[i-2]+nums[i]
不考虑i:dp[i-1]
初始化要按照实际情况来
class Solution(object):
def rob(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
n = len(nums)
dp = [0] * n
if n == 1:
return nums[0]
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[n-1]
环形数组,拆成两个线性数组分别计算
class Solution(object):
def rob(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
if len(nums) == 0:
return 0
if len(nums) == 1:
return nums[0]
nums1 = nums[:-1]
nums2 = nums[1:]
maxn1 = self.rb(nums1)
maxn2 = self.rb(nums2)
return max(maxn1,maxn2)
def rb(self,nums):
n = len(nums)
dp = [0] * n
if n == 1:
return nums[0]
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[n-1]
树形dp数组,每个节点返回一个size为2的dp数组
下标为0记录不偷该节点所得到的的最大金钱,下标为1记录偷该节点所得到的的最大金钱。
不偷本节点:左节点偷与不偷的最大值+右节点偷与不偷的最大值
偷本节点:本节点数值 + 不偷左孩子的值+不偷右孩子的值
class Solution(object):
def rob(self, root):
"""
:type root: TreeNode
:rtype: int
"""
return max(self.traversal(root))
def traversal(self,root):
if root is None:
return (0,0)
dp_left = self.traversal(root.left)
dp_right = self.traversal(root.right)
val1 = root.val + dp_left[0] + dp_right[0]
val2 = max(dp_left[0],dp_left[1]) + max(dp_right[0],dp_right[1])
return (val2,val1)