198. 打家劫舍:动态规划

简介: 这是 力扣上的 198. 打家劫舍,难度为 中等。

题目描述

这是 力扣上的 198. 打家劫舍,难度为 中等

image.png

题目分析

查看咱们给出的题目和示例,我们可以知道,对于偷窃这件事情,咱们不能做,但是题我们还是可以好好实现一波的

偷和不偷是一个问题

对于偷窃最高现金,再加上题目限制咱们不能太贪心,不能偷挨着的两家房屋,那么为了偷到最高现金,自然咱们只有 2 种选择,要么偷单数,要么偷双数,但是我们需要清晰的知道,并不是偷例如序号为 1,3,5,7... ,或者偷 0,2,4,6... 这样是不对的

毕竟对于一个 nums=[2,1,1,2] 的时候,咱们偷的情况其实就是 第 0 个和 第 3 个,也就是并不是全偷单数,或者全偷双数

那么,我们就可以这样来思考了:

对于 nums 长度为 0 的时候,咱们自然返回 0 即可

对于 nuns 长度为 1 的时候,自然返回 nums[0] 即可

对于 nums 长度为 2 的时候,自然是返回 max(nums[0], nums[1]) 即可

但是对于 nums 长度大于 2 的时候,我们需要如何去处理这些数据呢?

面对一个索引为 i 的房间,我们此时如果能获取最大的现金,那么对于我们来说,我们有 2 个选择,投第 i 这间房,或者不偷

如果偷:

相当于目前最高现金是: i-2 前面的房间偷的最高现金 加上 nums[i]

如果不偷:

相当于目前最高现金是:i-1 前面的房间偷的最高现金

此时,咱们使用动态规划,dp 数组来表示,索引 i 对应的房间,目前偷到的最高现金,则有

dp[0] = nums[0]

dp[1] = max(nums[0], nums[1])

dp[2] = max(nums[2] + dp[0] , dp[1])

...

那么,我们就有递推公式:

当i=0,dp[0]=nums[0]当 i = 0, dp[0] = nums[0]i=0,dp[0]=nums[0]

当i=1,dp[1]=max(nums[0],nums[1])当 i = 1, dp[1] = max(nums[0], nums[1])i=1,dp[1]=max(nums[0],nums[1])

当i>=2,dp[i]=max(nums[i]+dp[i−2],dp[i−1])当 i >=2,dp[i] = max(nums[i ] + dp[i-2], dp[i-1])i>=2dp[i]=max(nums[i]+dp[i2],dp[i1])

接下来,咱们就可以来实现编码了,咱们这次使用 golang 的方式来进行实现

Golang 的实现方式:

  • 校验 nums 的 0,1,2 的情况
  • 对于 nums 的长度为 2 以上的情况下,我们需要去维护好 dp 数组中的数据
  • 最后输出 dp[len(nums) - 1] 即可
func rob(nums []int) int {
    // 对于偷窃现金的,很明确,咱们只能间隔着偷,要么单数,要么双数,此处咱们可以使用动态规划的方式来进行处理
    // 因为当前的这个房间能够偷到最高的现金和,有 2 个选择,要么偷,要么不偷,偷当前这一间,那么上一间就不能偷,只能偷上上间
    // 当前这间房的最高现金,也是依赖于投上一间或者上上间能够偷到最高现金,因此我们可以使用动态规划的方式来进行处理
    // 校验 nums 的长度
    n := len(nums)
    if n == 0{
        return 0
    }else if n == 1 {
        return nums[0]
    }else if n == 2{
        return max(nums[0], nums[1])
    }
    // nums 长度大于 2 的情况
    dp := make([]int, n)
    dp[0] = nums[0]
    dp[1] = max(nums[0], nums[1])
    for i:=2; i<n; i++ {
        dp[i] = max(nums[i]+dp[i-2],dp[i-1])
    }
    return dp[n-1]
}
func max(a, b int) int {
    if a>b {
        return a
    }
    return b
}

这种实现方式,咱们的时间复杂度是 O(n),空间复杂度也是 O(n) , 咱们引入了 dp 这个数组来进行存储第 i 个房间能偷到的最大现金,实际上咱们也是可以将空间复杂度降低为 O(1),感兴趣的,可以评论留言哦

今天就到这里,若有偏差,还请斧正

欢迎点赞,关注,收藏

朋友们,你的支持和鼓励,是我坚持分享,提高质量的动力

image.png

好了,本次就到这里

技术是开放的,我们的心态,更应是开放的。拥抱变化,向阳而生,努力向前行。

我是阿兵云原生,欢迎点赞关注收藏,下次见~


相关文章
|
4月前
|
机器学习/深度学习 消息中间件 Kubernetes
动态规划-线性DP问题总结(一)
动态规划-线性DP问题总结(一)
【动态规划】198. 打家劫舍
【动态规划】198. 打家劫舍
|
7月前
|
算法
【学会动态规划】最大子数组和(19)
【学会动态规划】最大子数组和(19)
25 0
|
4月前
代码随想录 Day40 动态规划08 LeetCodeT198打家劫舍 T213打家劫舍II T337 打家劫舍III
代码随想录 Day40 动态规划08 LeetCodeT198打家劫舍 T213打家劫舍II T337 打家劫舍III
29 0
|
7月前
|
算法
【学会动态规划】打家劫舍 II(12)
【学会动态规划】打家劫舍 II(12)
12 0
|
10月前
|
Go Cloud Native
213. 打家劫舍 II:动态规划
这是 力扣上的 213. 打家劫舍 II,难度为 中等。
|
10月前
|
机器学习/深度学习 Cloud Native Go
337.打家劫舍 III:动态规划
这是力扣上的 337. 打家劫舍 III,难度为 中等。
|
12月前
动态规划-打家劫舍和股票买卖
前言 本篇文章我们来学习下动态规划中的两个经典题型,打家劫舍和股票买卖,通过两个题型来巩固动态规划解题思路。
|
算法 Java Python
【LeetCode】 53. 最大子序和(动态规划)
53. 最大子序和(动态规划)
77 0
【LeetCode】 53. 最大子序和(动态规划)
爬楼梯(动态规划)
假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
47 0