1.简单版:数组
198. 打家劫舍 - 力扣(LeetCode) (leetcode-cn.com)
时间复杂度:O(n)
空间复杂度:O(n)(可优化到O(1))
class Solution(object):
def rob(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
dp=[0 for _ in nums]
dp[0]=nums[0]
if len(nums)==1:
return dp[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[len(nums)-1]
2.进阶版:环形数组
213. 打家劫舍 II - 力扣(LeetCode) (leetcode-cn.com)
分两种情况:nums[:-1]和nums[1:]
时间复杂度:O(n)
空间复杂度:O(n)
代码如下:
class Solution(object):
def rob(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
if len(nums)==1:
return nums[0]
res=max(self.robNums(nums[:-1]),self.robNums(nums[1:]))
return res
def robNums(self,nums):
dp=[0 for _ in nums]
dp[0]=nums[0]
if len(nums)==1:
return dp[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[len(nums)-1]
3.进进阶版:二叉树
337. 打家劫舍 III - 力扣(LeetCode) (leetcode-cn.com)
一个错误的方法:理解为隔层打劫,所以计算每层的总和,得到一个nums,用【1】的方法算,然后是血的教训:过了部分用例。这个错误用例记住了!TAT
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution(object):
def rob(self, root):
"""
:type root: TreeNode
:rtype: int
"""
res=self.dp(root)
return max(res[0],res[1])
def dp(self,root):
if root is None:
return [0,0]
left=self.dp(root.left)
right=self.dp(root.right)
rob=root.val+left[0]+right[0]
not_rob=max(left[0],left[1])+max(right[0],right[1])
return [not_rob,rob]