[Golang]力扣Leetcode—初级算法—动态规划—打家劫舍
题目:
你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。
给定一个代表每个房屋存放金额的非负整数数组,计算你 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。
链接: 力扣Leetcode—初级算法—动态规划—打家劫舍.
示例1 :
输入:[1,2,3,1]
输出:4
解释:偷窃 1 号房屋 (金额 = 1) ,然后偷窃 3 号房屋 (金额 = 3)。
偷窃到的最高金额 = 1 + 3 = 4 。
示例2 :
输入:[2,7,9,3,1]
输出:12
解释:偷窃 1 号房屋 (金额 = 2), 偷窃 3 号房屋 (金额 = 9),接着偷窃 5 号房屋 (金额 = 1)。
偷窃到的最高金额 = 2 + 9 + 1 = 12 。
思路:
- 遍历到第一个数,这是第一家,以他家作为结束,那就把他偷了
- 遍历到第二个数,我们需要斟酌,如果第二家的财产更多就偷第二家,否则偷第一家
- 遍历到第三个数,我们需要分对第三家是偷还是不偷
偷第三家:那么第二家我们就不能偷,所以我们将第三家偷到的财产加上以第一家作为结束的最大财产,得到在截至第三家偷到所得的累加的总财产
不偷第三家:那么我们截至在第三家偷盗所得的总财产其实就是截至到第二家偷盗所得的总财产。
比较上面两种方式的大小,可以得到截至第三家累加的最大收益 - 遍历后续数组,每次只需要截至前两家的财产就可以计算出截至到当前家的最大收益
- 最后返回截至到最后一家的偷盗的收益
主要Go代码如下:
package main
import "fmt"
func rob(nums []int) int {
n := len(nums)
if n == 0 {
return 0
}
if n == 1 {
return nums[0]
}
if n > 1 {
// 如果第一家大于第二家,那么就偷第一家,否则就偷第二家
if nums[1] < nums[0] {
nums[1] = nums[0]
}
if n > 2 {
for i := 2; i < n; i++ {
// 偷第i家
if nums[i]+nums[i-2] >= nums[i-1] {
nums[i] += nums[i-2]
} else {
// 不偷第i家
nums[i] = nums[i-1]
}
}
}
}
return nums[n-1]
}
func main() {
a := []int{2, 7, 9, 3, 1}
fmt.Println(rob(a))
}
提交截图: