代码随想录算法训练营第四十八天| 198.打家劫舍、213.打家劫舍II、337.打家劫舍 III
198.打家劫舍
题目链接:198.打家劫舍
思路
求max,两种方式,不偷或偷搁家
解题代码
func rob(nums []int) int {
n := len(nums)
dp := make([]int, n+1) // dp[i]表示偷到第i家能够偷得的最大金额
dp[1] = nums[0]
for i := 2; i <= n; i++ {
dp[i] = max(dp[i-1], dp[i-2] + nums[i-1])
}
return dp[n]
}
func max(a, b int) int {
if a > b {
return a
}
return b
}
213.打家劫舍II
题目链接:213.打家劫舍II
思路
考虑两种情况的最大值,每种情况的结果是抢到倒数第二家的最大金额
解题代码
// 打家劫舍Ⅱ 动态规划
// 时间复杂度O(n) 空间复杂度O(n)
func rob(nums []int) int {
if len(nums) == 1 {
return nums[0]
}
if len(nums) == 2 {
return max(nums[0], nums[1])
}
result1 := robRange(nums, 0)
result2 := robRange(nums, 1)
return max(result1, result2)
}
// 偷盗指定的范围
func robRange(nums []int, start int) int {
dp := make([]int, len(nums))
dp[1] = nums[start]
for i := 2; i < len(nums); i++ {
dp[i] = max(dp[i - 2] + nums[i - 1 + start], dp[i - 1])
}
return dp[len(nums) - 1]
}
func max(a, b int) int {
if a > b {
return a
}
return b
}
337.打家劫舍 III
题目链接:337.打家劫舍 III
思路
后序遍历,考虑偷与不偷当前节点的两种情况最大值
解题代码
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func rob(root *TreeNode) int {
res := robTree(root)
return max(res[0], res[1])
}
func max(a, b int) int {
if a > b {
return a
}
return b
}
func robTree(cur *TreeNode) []int {
if cur == nil {
return []int{0, 0}
}
// 后序遍历
left := robTree(cur.Left)
right := robTree(cur.Right)
// 考虑去偷当前的屋子
robCur := cur.Val + left[0] + right[0]
// 考虑不去偷当前的屋子
notRobCur := max(left[0], left[1]) + max(right[0], right[1])
// 注意顺序:0:不偷,1:去偷
return []int{notRobCur, robCur}
}