LeetCode198.打家劫舍
题目链接:198. 打家劫舍
class Solution:
def rob(self, nums: List[int]) -> int:
n = len(nums)
if n <= 1:
return sum(nums)
dp = [0] * n
dp[0] = nums[0]
dp[1] = max(nums[0], nums[1])
for i in range(2, n):
dp[i] = max(dp[i-2] + nums[i], dp[i-1])
return dp[-1]
LeetCode213.打家劫舍Ⅱ
题目链接:213. 打家劫舍 II
# 二维dp
class Solution:
def rob(self, nums: List[int]) -> int:
if len(nums) <= 2:
return max(nums)
result_left = self.robRange(nums[:-1]) # 不打劫最后一个房子
result_right = self.robRange(nums[1:]) # 不打劫第一个房子
return max(result_left, result_right)
def robRange(self, nums: List[int]):
dp = [[0, 0] for _ in range(len(nums))]
dp[0][1] = nums[0]
for i in range(1, len(nums)):
dp[i][0] = max(dp[i-1])
dp[i][1] = dp[i-1][0] + nums[i]
return max(dp[-1])
# 一维dp
class Solution:
def rob(self, nums: List[int]) -> int:
if len(nums) <= 2:
return max(nums)
result_left = self.robRange(nums[:-1]) # 不打劫最后一个房子
result_right = self.robRange(nums[1:]) # 不打劫第一个房子
return max(result_left, result_right)
def robRange(self, nums: List[int]): #这个就是打家劫舍1的逻辑
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]
LeetCode337.打家劫舍Ⅲ
题目链接:337. 打家劫舍 III
# 暴力递归 -- 超时
# 时间复杂度O(n^2),空间复杂度O(logn)
class Solution:
def rob(self, root: Optional[TreeNode]) -> int:
if root is None:
return 0
if not root.left and not root.right:
return root.val
# 偷父节点
val_1 = root.val
if root.left:
val_1 += self.rob(root.left.left) + self.rob(root.left.right)
if root.right:
val_1 += self.rob(root.right.left) + self.rob(root.right.right)
# 不偷父节点
val_2 = self.rob(root.left) + self.rob(root.right)
return max(val_1, val_2)
# 记忆化递归
# 时间复杂度O(n),空间复杂度O(logn)
class Solution:
def __init__(self):
self.map = defaultdict(int)
def rob(self, root: Optional[TreeNode]) -> int:
if root is None:
return 0
if not root.left and not root.right:
return root.val
if self.map[root]:
return self.map[root]
# 偷父节点
val_1 = root.val
if root.left:
val_1 += self.rob(root.left.left) + self.rob(root.left.right)
if root.right:
val_1 += self.rob(root.right.left) + self.rob(root.right.right)
# 不偷父节点
val_2 = self.rob(root.left) + self.rob(root.right)
self.map[root] = max(val_1, val_2)
return max(val_1, val_2)
# dp
class Solution:
# 返回的是长度为2的数组,dp[0]表示不偷该结点,dp[1]表示偷该结点
def robTree(self, root: Optional[TreeNode]) -> List[int]:
if not root:
return [0, 0]
left = self.robTree(root.left)
right = self.robTree(root.right)
# 偷父节点
val_1 = root.val + left[0] + right[0]
# 不偷父节点
val_2 = max(left) + max(right)
return [val_2, val_1]
def rob(self, root: Optional[TreeNode]) -> int:
result = self.robTree(root)
return max(result)