题目描述
https://leetcode-cn.com/problems/house-robber/
https://leetcode-cn.com/problems/house-robber-iii/
思路题解
打家劫舍
用动态规划的思想,把问题简单化:
- 若当前有0间房屋:ans=0
- 若当前有1间房屋:ans=这1间房屋的金额
- 若当前有2间房屋:ans=这2间房屋的金额的最大值
- 若当前有3间房屋:ans=第2间和第1+3间的最大值
- 若当前有n(n>3)间房屋:ans=选k(第k间+前k-2间之和的金额)和不选k(前k-1间的金额)的最大值
python代码如下:
class Solution:
def rob(self, nums: List[int]) -> int:
length=len(nums)
if length<=3:
if length==0:return 0
if length==1:return nums[0]
if length==2:return max(nums[0],nums[1])
if length==3:return max(nums[1],nums[0]+nums[2])
dp={}
dp[0]=nums[0]
dp[1]=max(nums[0],nums[1])
dp[2]=max(nums[1],nums[0]+nums[2])
for i in range(3,length):
dp[i]=max(nums[i]+dp[i-2],dp[i-1])
return dp[length-1]
go代码如下:
借助数组版
func Max(a,b int) int{
if a>b{
return a
}else{
return b
}
}
func rob(nums []int) int {
length:=len(nums)
switch length{
case 0:return 0
case 1:return nums[0]
case 2:return Max(nums[0],nums[1])
case 3:return Max(nums[1],nums[0]+nums[2])
default:
dp:=map[int]int{
0:nums[0],
1:Max(nums[0],nums[1]),
2:Max(nums[1],nums[0]+nums[2]),
}
for i:=3;i<length;i++{
dp[i]=Max(nums[i]+dp[i-2],dp[i-1])
}
return dp[length-1]
}
}
不借助数组版:
func rob(nums []int) int {
if len(nums) <= 0 {
return 0
}
if len(nums) >= 2 {
nums[1] = max(nums[0], nums[1])
}
for i := 2; i < len(nums); i++ {
nums[i] = max(nums[i-2]+nums[i], nums[i-1])
}
return nums[len(nums)-1]
}
func max(a, b int) int {
if a > b {
return a
}
return b
}
打家劫舍 III
https://leetcode-cn.com/problems/house-robber-iii/solution/da-jia-jie-she-iii-by-leetcode-solution/
# 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: TreeNode) -> int:
def dfs(root):
if not root:return 0,0
ls,ln=dfs(root.left)
rs,rn=dfs(root.right)
return root.val+ln+rn,max(ls,ln)+max(rs,rn)
return max(dfs(root))