来到了新的一块内容:打家劫舍问题。
You are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed, the only constraint stopping you from robbing each of them is that adjacent houses have security systems connected and it will automatically contact the police if two adjacent houses were broken into on the same night.
Given an integer array
nums
representing the amount of money of each house, return the maximum amount of money you can rob tonight without alerting the police.
直觉告诉我,可能会涉及到一些贪心问题,为了保证利益最大,可能要找钱最多的地方优先动手。而当前房屋偷与不偷取决于,前一个房屋和前两个房屋是否被偷了。
仍然可以利用动态规划五部曲来解决。
dp[i] 是根据dp[i - 2] 和 dp[i - 1] 推导出来的,那么一定是从前到后遍历!
- class Solution:
- def rob(self, nums: List[int]) -> int:
- if len(nums) == 0:
- return 0
- if len(nums) == 1:
- return nums[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 - 2] + nums[i], dp[i - 1])
-
- return dp[-1]
You are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed. All houses at this place are arranged in a circle. That means the first house is the neighbor of the last one. Meanwhile, adjacent houses have a security system connected, and it will automatically contact the police if two adjacent houses were broken into on the same night.
Given an integer array
nums
representing the amount of money of each house, return the maximum amount of money you can rob tonight without alerting the police.
和前一题比较,这道题变成环状了,需要考虑下面三个因素:
对于一个数组,成环的话主要有如下三种情况:
- class Solution:
- def rob(self, nums: List[int]) -> int:
- if not nums: # 如果没有房屋,返回0
- return 0
-
- if len(nums) == 1: # 如果只有一个房屋,返回该房屋的金额
- return nums[0]
-
- # 情况二:不抢劫第一个房屋
- prev_max = 0 # 上一个房屋的最大金额
- curr_max = 0 # 当前房屋的最大金额
- for num in nums[1:]:
- temp = curr_max # 临时变量保存当前房屋的最大金额
- curr_max = max(prev_max + num, curr_max) # 更新当前房屋的最大金额
- prev_max = temp # 更新上一个房屋的最大金额
- result1 = curr_max
-
- # 情况三:不抢劫最后一个房屋
- prev_max = 0 # 上一个房屋的最大金额
- curr_max = 0 # 当前房屋的最大金额
- for num in nums[:-1]:
- temp = curr_max # 临时变量保存当前房屋的最大金额
- curr_max = max(prev_max + num, curr_max) # 更新当前房屋的最大金额
- prev_max = temp # 更新上一个房屋的最大金额
- result2 = curr_max
-
- return max(result1, result2)
The thief has found himself a new place for his thievery again. There is only one entrance to this area, called
root
.Besides the
root
, each house has one and only one parent house. After a tour, the smart thief realized that all houses in this place form a binary tree. It will automatically contact the police if two directly-linked houses were broken into on the same night.Given the
root
of the binary tree, return the maximum amount of money the thief can rob without alerting the police.
本题一定是要后序遍历,因为通过递归函数的返回值来做下一步计算。
- class Solution:
- def rob(self, root: TreeNode) -> int:
- if root is None:
- return 0
- if root.left is None and root.right is None:
- return root.val
- # 偷父节点
- val1 = root.val
- if root.left:
- val1 += self.rob(root.left.left) + self.rob(root.left.right)
- if root.right:
- val1 += self.rob(root.right.left) + self.rob(root.right.right)
- # 不偷父节点
- val2 = self.rob(root.left) + self.rob(root.right)
- return max(val1, val2)