今日专题 :动态规划、打家劫舍
总结:
198. 打家劫舍
class Solution:def rob(self, nums: List[int]) -> int:#dp[n]=max(dp[n-1],dp[n-2]+nums[n])size=len(nums)if size==1:return nums[0]#n的状态只依赖n-1和n-2的状态,对状态进行压缩i,j=nums[0],max(nums[0],nums[1])result=max(i,j)for n in range(2,size):result=max(j,i+nums[n])i,j=j,resultreturn result
213. 打家劫舍 II
思路:环形的打家劫舍
class Solution:def rob(self, nums: List[int]) -> int:# 环形的打家劫舍# 计算两个最大值 偷0 和不偷0# 偷0 则dp从2开始 size-2# 不偷0 dp从1开始到 size-1def robs(numList):if len(numList) < 2:return numList[0]i, j = 0, 0res = jfor n in numList:res = max(j, i + n)i, j = j, resreturn ressize = len(nums)if size <= 3:return max(nums)return max(robs(nums[2 : size - 1]) + nums[0], robs(nums[1:]))
337. 打家劫舍 III
思路:关键点在于把当前层选没选传递下去
1.如果上层节点没有被选,则当前节点可选可不选取最大值
2.如果上层节点被选,则当前节点只能不选
总结:以下解法一为我根据上述思路做出来的解法,其实不属于动态规划解法,每个节点被遍历两次,解法二从下往上返回不同选择的结果,并用子问题的结果一步步构建到根节点的结果
解法一:
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:def rob(self, root: Optional[TreeNode]) -> int:# 树形打家劫舍@cachedef dfs(node, flag):if node == None:return 0res1, res2 = 0, 0if node.left:res1 += dfs(node.left, False)if node.right:res1 += dfs(node.right, False)if not flag:res2 += node.valif node.left:res2 += dfs(node.left, True)if node.right:res2 += dfs(node.right, True)return max(res1, res2)return dfs(root, False)
解法二
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:def rob(self, root: Optional[TreeNode]) -> int:# dp数组(dp table)以及下标的含义:# 1. 下标为 0 记录 **不偷该节点** 所得到的的最大金钱# 2. 下标为 1 记录 **偷该节点** 所得到的的最大金钱dp = self.traversal(root)return max(dp)# 要用后序遍历, 因为要通过递归函数的返回值来做下一步计算def traversal(self, node):# 递归终止条件,就是遇到了空节点,那肯定是不偷的if not node:return (0, 0)left = self.traversal(node.left)right = self.traversal(node.right)# 不偷当前节点, 偷子节点val_0 = max(left[0], left[1]) + max(right[0], right[1])# 偷当前节点, 不偷子节点val_1 = node.val + left[0] + right[0]return (val_0, val_1)